fix(web): Keep running, stopped, and failed rows visible in the work log - #4762
fix(web): Keep running, stopped, and failed rows visible in the work log#4762mwolson wants to merge 331 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Keeping these rows in the work log exposed that the row component had no treatment for them, so they borrowed the wrong one. A stopped tool rendered a green check with a "Completed" tooltip once the turn settled, because the settled-turn fallback treats any neutral row as success. A running tool rendered the "Empty" dash, which is meant for rows with no content. Both now render their own state: a spinner tooltipped "Running" while the turn is live, and a square tooltipped "Stopped" for an interrupted tool. An `inProgress` row that outlives its turn is also shown as stopped rather than completed, since the turn ended without the tool ever reporting a result. Reported by Macroscope on pingdotgg#4762, which caught the stopped-as-completed half.
Keeping these rows in the work log exposed that the row component had no treatment for them, so they borrowed the wrong one. A stopped tool rendered a green check with a "Completed" tooltip once the turn settled, because the settled-turn fallback treats any neutral row as success. A running tool rendered the "Empty" dash, which is meant for rows with no content. Both now render their own state: a spinner tooltipped "Running" while the turn is live, and a square tooltipped "Stopped" for an interrupted tool. An `inProgress` row that outlives its turn is also shown as stopped rather than completed, since the turn ended without the tool ever reporting a result. Reported by Macroscope on pingdotgg#4762, which caught the stopped-as-completed half.
caf6f38 to
d30b4a7
Compare
Codex review of pingdotgg#4762 caught that inferring "stopped" from a settled turn is wrong. `activeTurnInProgress` is thread-wide, and background work legitimately outlives the root run: `RunExecutionService` explicitly keeps ingesting a late background command completion after root terminal, in the order running -> root-finalized -> completed. The inference would have labelled that live work "Stopped" and then jumped it to "Completed". Both indicators now read the item's own lifecycle and nothing else. A genuine interrupt already terminalizes the item at the projection layer, which is what made the inference look unnecessary rather than harmful. Also from that review: - The work group's filter is now `workEntryShouldRenderInWorkLog`, a production helper, so the predicate tests exercise the shipped policy instead of a copy of the expression that could drift from it. - The lifecycle joins the row's accessible name ("Ran command …, running"), since the indicator sits inside the row button and did not contribute to it. The spinner is decorative rather than a nested role="status" announcing a generic "Loading". - Component tests cover running during an active turn, running after settle, stopped in both states, and a signal-less row staying hidden. Tooltip text is absent from static markup, so they assert on the icon and accessible name, as the existing failed-indicator test does.
Keeping these rows in the work log exposed that the row component had no treatment for them, so they borrowed the wrong one. A stopped tool rendered a green check with a "Completed" tooltip once the turn settled, because the settled-turn fallback treats any neutral row as success. A running tool rendered the "Empty" dash, which is meant for rows with no content. Both now render their own state: a spinner tooltipped "Running" while the turn is live, and a square tooltipped "Stopped" for an interrupted tool. An `inProgress` row that outlives its turn is also shown as stopped rather than completed, since the turn ended without the tool ever reporting a result. Reported by Macroscope on pingdotgg#4762, which caught the stopped-as-completed half.
Codex review of pingdotgg#4762 caught that inferring "stopped" from a settled turn is wrong. `activeTurnInProgress` is thread-wide, and background work legitimately outlives the root run: `RunExecutionService` explicitly keeps ingesting a late background command completion after root terminal, in the order running -> root-finalized -> completed. The inference would have labelled that live work "Stopped" and then jumped it to "Completed". Both indicators now read the item's own lifecycle and nothing else. A genuine interrupt already terminalizes the item at the projection layer, which is what made the inference look unnecessary rather than harmful. Also from that review: - The work group's filter is now `workEntryShouldRenderInWorkLog`, a production helper, so the predicate tests exercise the shipped policy instead of a copy of the expression that could drift from it. - The lifecycle joins the row's accessible name ("Ran command …, running"), since the indicator sits inside the row button and did not contribute to it. The spinner is decorative rather than a nested role="status" announcing a generic "Loading". - Component tests cover running during an active turn, running after settle, stopped in both states, and a signal-less row staying hidden. Tooltip text is absent from static markup, so they assert on the icon and accessible name, as the existing failed-indicator test does.
…eachable Codex round 2 on pingdotgg#4762. Once `workEntryShouldRenderInWorkLog` admits neutral rows only when they carry a reported lifecycle, the row's neutral handling can never fire: `showNeutralIndicator` and the settled-turn success fallback both require the opposite. So `turnSettled`, `hasReportedLifecycle`, `showNeutralIndicator`, the "Empty" dash branch, and the compound success expression were all dead. Success is now just `workEntryIndicatesToolSuccess`, and the row no longer reads thread-wide turn state at all. Also from that round: - Tests pin "no stopped indicator" properly. A stopped row could have regressed to the dash while every assertion still passed; there is now a negative `lucide-minus` check, and the running case asserts the spinner carries neither `role="status"` nor `aria-label="Loading"`, so the accessibility fix cannot silently revert. - The comment claiming both states get their own indicator is gone, as is the overstatement that a "Run interrupted" divider always sits beneath a stopped row: `cancelled` maps to stopped too and has no such row.
…eachable Codex round 2 on pingdotgg#4762. Once `workEntryShouldRenderInWorkLog` admits neutral rows only when they carry a reported lifecycle, the row's neutral handling can never fire: `showNeutralIndicator` and the settled-turn success fallback both require the opposite. So `turnSettled`, `hasReportedLifecycle`, `showNeutralIndicator`, the "Empty" dash branch, and the compound success expression were all dead. Success is now just `workEntryIndicatesToolSuccess`, and the row no longer reads thread-wide turn state at all. The running test also asserts the spinner carries neither `role="status"` nor `aria-label="Loading"`, so the accessibility fix cannot silently revert. The comment claiming both states get their own indicator is gone, as is the overstatement that a "Run interrupted" divider always sits beneath a stopped row: `cancelled` maps to stopped too and has no such row.
5a7eae3 to
257f810
Compare
…eachable Codex round 2 on pingdotgg#4762. Once `workEntryShouldRenderInWorkLog` admits neutral rows only when they carry a reported lifecycle, the row's neutral handling can never fire: `showNeutralIndicator` and the settled-turn success fallback both require the opposite. So `turnSettled`, `hasReportedLifecycle`, `showNeutralIndicator`, the "Empty" dash branch, and the compound success expression were all dead. Success is now just `workEntryIndicatesToolSuccess`, and the row no longer reads thread-wide turn state at all. The running test also asserts the spinner carries neither `role="status"` nor `aria-label="Loading"`, so the accessibility fix cannot silently revert. The comment claiming both states get their own indicator is gone, as is the overstatement that a "Run interrupted" divider always sits beneath a stopped row: `cancelled` maps to stopped too and has no such row.
257f810 to
365949a
Compare
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This production timeline change alters existing work-log visibility and lifecycle rendering but leaves collapsed-group behavior unwired and contains type-check/integration inconsistencies. Provider errors and stopped or running rows are not consistently represented by the shipped renderer, so human review is needed. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
Macroscope on pingdotgg#4762. `projectedWorkEntryStatus` collapses `pending`, `running`, and `waiting` into `inProgress`, so keying the spinner off `toolLifecycleStatus` made a queued tool and an approval request blocked on the user both claim to be running, with a "running" tooltip and accessible suffix to match. That was a regression from this PR: before it, those rows reached the indicator chain with no branch that applied and rendered nothing. `workEntryIsExecuting` reads the projected item's real status instead, so only a genuinely running tool spins. `pending` and `waiting` rows still render, since showing in-flight work is the point of the PR, but they claim nothing. The test helper now derives the projected status from the collapsed lifecycle value, so a fixture cannot assert on a pairing the projection never emits; the previous version let a `stopped` row carry a `running` item.
Dismissing prior approval to re-evaluate 7d5e55c
…eachable Codex round 2 on pingdotgg#4762. Once `workEntryShouldRenderInWorkLog` admits neutral rows only when they carry a reported lifecycle, the row's neutral handling can never fire: `showNeutralIndicator` and the settled-turn success fallback both require the opposite. So `turnSettled`, `hasReportedLifecycle`, `showNeutralIndicator`, the "Empty" dash branch, and the compound success expression were all dead. Success is now just `workEntryIndicatesToolSuccess`, and the row no longer reads thread-wide turn state at all. The running test also asserts the spinner carries neither `role="status"` nor `aria-label="Loading"`, so the accessibility fix cannot silently revert. The comment claiming both states get their own indicator is gone, as is the overstatement that a "Run interrupted" divider always sits beneath a stopped row: `cancelled` maps to stopped too and has no such row.
Macroscope on pingdotgg#4762. `projectedWorkEntryStatus` collapses `pending`, `running`, and `waiting` into `inProgress`, so keying the spinner off `toolLifecycleStatus` made a queued tool and an approval request blocked on the user both claim to be running, with a "running" tooltip and accessible suffix to match. That was a regression from this PR: before it, those rows reached the indicator chain with no branch that applied and rendered nothing. `workEntryIsExecuting` reads the projected item's real status instead, so only a genuinely running tool spins. `pending` and `waiting` rows still render, since showing in-flight work is the point of the PR, but they claim nothing. The test helper now derives the projected status from the collapsed lifecycle value, so a fixture cannot assert on a pairing the projection never emits; the previous version let a `stopped` row carry a `running` item.
Cancel pending SDK requests before aborting the native session. Preserve per-admission cancellation state and treat stopped initial prompts as interruption instead of provider failure. Finding: R14 prompt cancellation Model: GPT-5.6 Sol via Codex
Keep the original cursor owner through ancestor traversal and preserve the history budget across empty intermediate forks. Verify exact paged history against the complete nested projection. Finding: P01 nested lineage Model: GPT-5.6 Sol via Codex
Retain pending admission after transient status failures and use one generation-owned retry worker. Ignore stale timers and duplicate evidence so older prompts cannot finish newer steering. Finding: R14 status reconciliation Model: GPT-5.6 Sol via Codex
Keep hidden local and inherited rows from consuming history pages. Preserve stop-request dependencies, source-run cutoffs, and imported history while loading related metadata from the selected cohort and using indexed watermark lookups. Finding: P01 bounded history visibility Model: GPT-5.6 Sol via Codex
Adapt grouped tool summaries and the floating working timer to V2 run, attempt, and queue state. Bring over the composer, keyboard, and disclosure transitions while retaining the V2 activity inspector and queue controls. Keep OV2 web composer and grouping behavior intact; share only the existing command label parser with mobile.
Restores main features dropped by the policy replay: pingdotgg#8569 theme wiring, pingdotgg#8850 composer banner follow-ups, pingdotgg#8855/pingdotgg#8904 composer fixes, pingdotgg#8831 settings search rework, pingdotgg#8803 workspace-mutation refresh (v2-adapted), pingdotgg#8840 circle-alert, pingdotgg#8584 codex artifact templates, pingdotgg#8688/pingdotgg#8807/pingdotgg#8936 video + image previews (web and mobile, v2-adapted), pingdotgg#8862 Expo glass, and the round's docs. Timeline thinking rows (pingdotgg#8984) stay on the v2 work-live system. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
a6e0049 to
50a57b6
Compare
The v2 equivalents of main's pingdotgg#8984 and pingdotgg#8922: a "Working for ..." header anchors the active run, the trailing live tool row survives between actions in past tense instead of vanishing, and a shimmering Thinking row marks reasoning gaps. During workspace preparation the header shows "Setting up worktree..." (driven by the local dispatch flag or the v2 run's preparing status, so remote viewers see it too), the composer footer span is gone, and draft promotion waits until the run starts or startup fails instead of navigating mid-preparation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
38109f8 to
a9f243a
Compare
Dismissing prior approval to re-evaluate a9f243a
| if ( | ||
| entry.id !== group.terminalEntry?.id && | ||
| !timelineEntryIsPersistentResourceCard(entry) && | ||
| !timelineEntryIsTerminalError(entry) |
There was a problem hiding this comment.
🟡 Medium chat/MessagesTimeline.logic.ts:783
A failed itemType: "error" with tone: "info" is rendered as a generic work-toggle instead of a work error row, so the provider error detail remains hidden and the expected provider-error-entry row never appears. deriveTurnFolds now leaves these entries visible, but the rendering branch only recognizes tone === "error"; update that branch to also recognize timelineEntryIsTerminalError.
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/chat/MessagesTimeline.logic.ts around line 783:
A failed `itemType: "error"` with `tone: "info"` is rendered as a generic `work-toggle` instead of a `work` error row, so the provider error detail remains hidden and the expected `provider-error-entry` row never appears. `deriveTurnFolds` now leaves these entries visible, but the rendering branch only recognizes `tone === "error"`; update that branch to also recognize `timelineEntryIsTerminalError`.
There was a problem hiding this comment.
Two of these findings look like fallout from rebasing onto t3code/codex-turn-mapping: the collapsed work-log UI this PR's round-4 repair targets (a per-group visible cap and a "+N previous tool calls" expander) does not exist on this base, so the new selector, its constant, and the component tests written against it have nothing to attach to.
Posted via Macroscope — UI Consistency
| export function selectCollapsedWorkLogEntries( | ||
| nonEmptyEntries: readonly WorkLogEntry[], | ||
| ): WorkLogEntry[] { | ||
| if (nonEmptyEntries.length <= MAX_VISIBLE_WORK_LOG_ENTRIES) { |
There was a problem hiding this comment.
MAX_VISIBLE_WORK_LOG_ENTRIES is neither declared in this module nor imported (the import block ends at line 31, and the only local constants are the TIMELINE_* ones at 60-64). tsgo --noEmit fails here with Cannot find name 'MAX_VISIBLE_WORK_LOG_ENTRIES', and if it were bundled the function would throw ReferenceError on first call.
The function also has no production consumer: MessagesTimeline.tsx imports workEntryIsVisibleInGroup and friends from this module but not selectCollapsedWorkLogEntries, and on this base a work group renders as a work-live or work-toggle row (derivation around line 1075) with no per-group visible cap to collapse — so the pinning behavior described in the doc comment never reaches the UI.
Suggest either wiring the selection into the work-group derivation and defining the cap it depends on, or dropping the function together with its tests until the collapsed work-log UI exists on this branch.
Posted via Macroscope — UI Consistency
| workingStepLabel?: string | null; | ||
| pendingBackgroundTasks?: ReadonlyArray<{ | ||
| readonly taskId: string; | ||
| readonly description?: string | undefined; | ||
| }> | null; |
There was a problem hiding this comment.
workingStepLabel and pendingBackgroundTasks are added to the props contract and destructured with defaults (lines 305-306), but nothing in the component reads them: ChatView passes pendingBackgroundTasks to the composer, not the timeline, and never passes workingStepLabel. This grows the timeline's public prop surface with no renderer behind it, which is easy to mistake for supported behavior at a future call site.
Suggest dropping both until a consumer needs them (the destructured defaults at 305-306 need to go with them):
isPreparingWorktree?: boolean;
- workingStepLabel?: string | null;
- pendingBackgroundTasks?: ReadonlyArray<{
- readonly taskId: string;
- readonly description?: string | undefined;
- }> | null;
listRef: React.RefObject<LegendListRef | null>;Posted via Macroscope — UI Consistency
| structuredPayload: { status: row.itemStatus } as OrchestrationV2TurnItem, | ||
| }, | ||
| }; | ||
| }); | ||
|
|
||
| // Collapsed groups used to keep only slice(-1), so a later completed tool | ||
| // buried the running or stopped row the work-log filter retained. | ||
| it("keeps pinned running and stopped tools visible in a collapsed work group", () => { | ||
| const runningAndCompleted = renderToStaticMarkup( | ||
| <MessagesTimeline | ||
| {...buildProps()} | ||
| timelineEntries={multiToolWorkEntries([ | ||
| { id: "running", label: "Active shell", itemStatus: "running" }, | ||
| { id: "completed", label: "Finished shell", itemStatus: "completed" }, | ||
| ])} | ||
| />, | ||
| ); | ||
| expect(runningAndCompleted).toContain("Active shell"); | ||
| expect(runningAndCompleted).toContain("Finished shell"); | ||
| expect(runningAndCompleted).toContain("lucide-loader-circle"); | ||
| expect(runningAndCompleted).not.toContain("previous tool"); | ||
|
|
||
| const stoppedAndCompleted = renderToStaticMarkup( | ||
| <MessagesTimeline | ||
| {...buildProps()} | ||
| timelineEntries={multiToolWorkEntries([ | ||
| { id: "stopped", label: "Interrupted shell", itemStatus: "interrupted" }, | ||
| { id: "completed", label: "Finished shell", itemStatus: "completed" }, | ||
| ])} | ||
| />, | ||
| ); | ||
| expect(stoppedAndCompleted).toContain("Interrupted shell"); | ||
| expect(stoppedAndCompleted).toContain("Finished shell"); | ||
| expect(stoppedAndCompleted).toContain(', stopped"'); | ||
| expect(stoppedAndCompleted).not.toContain("previous tool"); | ||
| }); | ||
|
|
||
| it("does not pin pending or waiting rows in a collapsed work group", () => { | ||
| const markup = renderToStaticMarkup( | ||
| <MessagesTimeline | ||
| {...buildProps()} | ||
| timelineEntries={multiToolWorkEntries([ | ||
| { id: "pending", label: "Queued shell", itemStatus: "pending" }, | ||
| { id: "waiting", label: "Blocked shell", itemStatus: "waiting" }, | ||
| { id: "completed", label: "Finished shell", itemStatus: "completed" }, | ||
| ])} | ||
| />, | ||
| ); | ||
|
|
||
| expect(markup).toContain("Finished shell"); | ||
| expect(markup).not.toContain("Queued shell"); | ||
| expect(markup).not.toContain("Blocked shell"); | ||
| expect(markup).toContain("+2 previous tool calls"); |
There was a problem hiding this comment.
These collapsed-work-group cases assert against UI that does not exist on this target branch. Work groups render row.summary through WorkGroupToggleTimelineRow (e.g. Ran 2 commands), there is no +N previous tool calls expander string anywhere in MessagesTimeline.tsx, and no per-group visible cap that could hide Queued shell/Blocked shell — so both the pinned-row and the not-pinned expectations fail rather than guarding the fix.
Suggest retargeting them at the work-live/work-toggle row model (or removing them alongside the unused selectCollapsedWorkLogEntries) so the suite matches the shipped work-group rendering.
Posted via Macroscope — UI Consistency
| isWorking={isWorking} | ||
| activeTurnInProgress={isWorking || !latestRunSettled} | ||
| activeTurnStartedAt={activeWorkStartedAt} |
There was a problem hiding this comment.
activeTurnInProgress is still a required prop on MessagesTimelineProps (chat/MessagesTimeline.tsx:236) and this is its only production call site, so dropping the attribute makes apps/web fail typecheck with Property 'activeTurnInProgress' is missing in type ... but required in type 'MessagesTimelineProps'.
Nothing reads the value anymore either — SimpleWorkEntryRow now derives indicators from the item's own status, and the prop is only copied into TimelineRowActivityState (declared at line 199, populated at line 654) where no consumer reads that field. Suggest completing the removal: delete the prop from MessagesTimelineProps, the destructured binding at line 302, the TimelineRowActivityState field and its activityState entry/dep, and the three usages in MessagesTimeline.test.tsx (buildProps, and the JSX at lines 805 and 1929).
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a9f243a. Configure here.
| entry.id !== group.terminalEntry?.id && | ||
| !timelineEntryIsPersistentResourceCard(entry) && | ||
| !timelineEntryIsTerminalError(entry) | ||
| ) { |
There was a problem hiding this comment.
Collapsed groups hide pinned tool rows
High Severity
selectCollapsedWorkLogEntries is never used when building or rendering work groups. Settled groups still emit only a work-toggle that hides every row, so running and stopped tools stay behind the summary instead of remaining visible in the compact log. The +N previous tool calls expander the new tests expect is also never rendered.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit a9f243a. Configure here.
| entry.id !== group.terminalEntry?.id && | ||
| !timelineEntryIsPersistentResourceCard(entry) && | ||
| !timelineEntryIsTerminalError(entry) | ||
| ) { |
There was a problem hiding this comment.
Failed errors stay behind work toggle
Medium Severity
deriveTurnFolds now keeps failed itemType === "error" entries out of the turn fold, but row emission still treats projected provider errors as ordinary work because their tone is info. They become a work-toggle labeled Provider error, so the failure detail stays hidden unless the group is expanded.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit a9f243a. Configure here.
6081201 to
95bacdd
Compare


What Changed
The web work log keeps the rows that tell you what a turn is doing. Running tools stay in the log with a spinner. Interrupted tools stay visible without a success check. Collapsed work logs still show an active or interrupted tool even when newer rows would have pushed it out.
When a provider fails and the turn has no assistant message, the failed error stays in the timeline instead of only the sidebar. Recovered retries still fold like ordinary work.
Why
The server already had the right items. The web timeline treated running and interrupted tools like noise. When a finished turn collapsed its work log, it kept a final assistant message but hid a failed error, so the error only showed in the sidebar.
This is web-only. Mobile does not share these filters.
UI Changes
Running and stopped tool rows remain visible, including in compact work logs. Failed provider errors remain visible on settled turns with no assistant message. Stopped tools have no extra glyph. The interrupt row still carries the stop marker.
No before/after screenshots. Checked on a Codex turn in the web app: a foreground command showed a spinner while running, and after Stop the row stayed without a spinner or success check. A live failed provider turn had the error folded away before this change.
Checklist
Note
Medium Risk
Changes chat timeline visibility and fold rules for work entries and provider errors; incorrect lifecycle mapping could hide or mislabel in-flight tools, but scope is web UI presentation only.
Overview
The chat work log now keeps tool rows that have a real lifecycle (running, queued/waiting, stopped) instead of treating them as hideable noise, and collapsed tool groups pin genuinely running or stopped tools so a later completed row cannot bury them.
Lifecycle UI is driven per work entry (
structuredPayload.status), not thread-wide turn state: running tools get a spinner, completed/failed keep check/X, pending/waiting show no misleading glyph, and stopped tools stay visible without a success check.ChatViewstops passingactiveTurnInProgressintoMessagesTimelinefor this behavior.Settled turns no longer fold away terminal provider errors when there is no assistant message, so capacity/failure errors stay on the main timeline. Session-logic adds
workEntryShouldRenderInWorkLog,workEntryIsExecuting, andselectCollapsedWorkLogEntriesto encode the filtering and collapse rules, with broad unit/component tests.Reviewed by Cursor Bugbot for commit a9f243a. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Keep running, stopped, and failed work log rows visible in
MessagesTimelineworkEntryShouldRenderInWorkLog,workEntryIsExecuting, andworkEntryHasReportedLifecycleutilities in session-logic.ts to define which neutral rows still convey lifecycle information and should stay visibleselectCollapsedWorkLogEntriesin MessagesTimeline.logic.ts to pin executing and stopped tool rows alongside the latest ordinary entries when a work group is collapsedSimpleWorkEntryRowin MessagesTimeline.tsx: shows a spinner for running tools, drops the neutralMinusIconindicator for pending/waiting/stopped, and appends lifecycle suffixes (, running,, stopped,, failed) to the row's accessible nametimelineEntryIsTerminalErrorso they remain visible when a turn settlesworkEntryIsVisibleInGroupandselectCollapsedWorkLogEntriesin MessagesTimeline.logic.ts for edge cases where too many pinned rows exceedMAX_VISIBLE_WORK_LOG_ENTRIES📊 Macroscope summarized a9f243a. 4 files reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted
🗂️ Filtered Issues