Skip to content

Redesign chat cards and make proof chronological and recoverable - #933

Merged
arul28 merged 20 commits into
mainfrom
ade/couple-thigns-wanna-dsicuss-first-d432760f
Jul 29, 2026
Merged

Redesign chat cards and make proof chronological and recoverable#933
arul28 merged 20 commits into
mainfrom
ade/couple-thigns-wanna-dsicuss-first-d432760f

Conversation

@arul28

@arul28 arul28 commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • redesign desktop chat cards around responsive shared row/card primitives
  • render proof chronologically in the turn where it was captured, with collapsible desktop and compact mobile treatments
  • make proof ingestion lane-aware, recoverable, securely jailed, and deletable across desktop, CLI, storage cleanup, and sync
  • keep PR/CI card detail honest across degraded refreshes on desktop, ADE Code, and iOS

Validation

  • /quality dual review completed; blocker/high findings fixed
  • /test completed with docs, CLI, TUI, and mobile parity
  • affected desktop CI shards passed
  • ADE CLI: 2,432 tests passed
  • ADE Code TUI: 1,022 tests passed
  • targeted iOS proof/card tests passed on iPhone 17 Pro simulator

ADE   Open in ADE  ·  ade/couple-thigns-wanna-dsicuss-first-d432760f branch  ·  PR #933

Summary by CodeRabbit

  • New Features
    • Expanded ade proof with ingest/attach, remove, broken listing, prune-broken, and recover flows; added support for ade-artifact://project/... URIs.
    • Added computer-use artifact maintenance operations end-to-end (desktop IPC/preload/IPC, storage cleanup for proof attachments).
    • Introduced lane-scoped proof handling and proof-card availability/broken states (including new duration metadata UI on supported clients).
  • Bug Fixes
    • Improved degraded refresh behavior to preserve prior rich detail; corrected truncation and “+N more” rendering.
    • Tightened proof ingestion/maintenance authorization and path safety.
  • Refactor
    • Migrated chat transcript/proof cards to shared card primitives and unified chat width/duration formatting.
  • Tests
    • Added/expanded coverage for maintenance flows, scoping, URI resolution, storage cleanup, and card rendering.

@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
ade Ignored Ignored Preview Jul 29, 2026 4:23am

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 33e860b5-470c-40f8-a105-1d9378bf4faa

📥 Commits

Reviewing files that changed from the base of the PR and between 1da24f8 and e8f2fc2.

📒 Files selected for processing (12)
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/main/services/storage/storageInsightsService.test.ts
  • apps/desktop/src/main/services/storage/storageInsightsService.ts
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.test.tsx
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx
  • apps/desktop/src/renderer/components/chat/chatTranscriptRows.test.ts
  • apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • apps/desktop/src/main/services/storage/storageInsightsService.ts
  • apps/desktop/src/renderer/components/chat/chatTranscriptRows.test.ts
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.test.tsx
  • apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/adeRpcServer.test.ts

📝 Walkthrough

Walkthrough

The PR adds lane-aware computer-use proof ingestion and lifecycle maintenance, exposes proof management through CLI, RPC, IPC, and preload APIs, synchronizes cleanup across storage and project operations, and updates desktop, TUI, and iOS card and proof rendering.

Changes

Proof artifacts and ADE cards

Layer / File(s) Summary
Artifact lifecycle and API surface
apps/desktop/src/main/services/computerUse/*, apps/ade-cli/src/*, apps/desktop/src/shared/*, apps/desktop/src/preload/*
Adds lane-scoped ingestion, authorization, deletion, broken-artifact listing, pruning, recovery, and corresponding CLI, RPC, IPC, and preload operations.
Storage and cleanup integration
apps/desktop/src/main/services/lanes/*, apps/desktop/src/main/services/projects/*, apps/desktop/src/main/services/storage/*, apps/desktop/src/main/main.ts, apps/ade-cli/src/bootstrap.ts
Removes proof records with deleted files, preserves shared artifacts, and scopes proof cleanup to approved storage roots.
Cross-client ADE card handling
apps/desktop/src/shared/adeCard.ts, apps/desktop/src/renderer/components/chat/*, apps/ade-cli/src/tuiClient/*, apps/ios/ADE/Views/Work/*, apps/ios/ADE/Models/*
Adds degraded-state metadata, duration formatting, truncation counts, stale-detail merging, shared card primitives, and client-specific card rendering.
Proof presentation and chat layout
apps/desktop/src/renderer/components/chat/*, apps/ios/ADE/Views/Work/*
Adds inline and collapsible proof displays, broken-artifact recovery and deletion controls, activity-card refactors, and shared transcript width handling.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • arul28/ADE#112: Related to local artifact preview handling and ade-artifact:// resolution.
  • arul28/ADE#797: Related to the storage cleanup pipeline extended for proof records.

Suggested labels: desktop, ios, docs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main changes: chat card redesign plus chronological, recoverable proof handling.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ade/couple-thigns-wanna-dsicuss-first-d432760f

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@arul28 arul28 changed the title proof-display-and-chat-loading-diagnosis -> Primary Redesign chat cards and make proof chronological and recoverable Jul 28, 2026
@arul28

arul28 commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 591065be66

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts Outdated
Comment thread apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts
Comment thread apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts Outdated
Comment thread apps/ios/ADE/Views/Work/WorkModels.swift Outdated
@arul28

arul28 commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48e8282893

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/services/lanes/laneService.ts
Comment thread apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx Outdated
@arul28

arul28 commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d3e4bc5b6

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/services/lanes/laneService.ts
Comment thread apps/ade-cli/src/tuiClient/format.ts Outdated
@arul28

arul28 commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 277be76fa8

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .gitleaksignore Outdated
Comment thread apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts Outdated
arul28 and others added 10 commits July 28, 2026 19:25
Cards
- One resizable --chat-content-width token replaces the fixed 832px column and
  seven disagreeing per-row clamps; cards no longer stop 26% short of prose.
- Shared chatCardPrimitives on a 16px/1fr/auto grid so titles, durations and
  counts align in columns down the transcript.
- CI cards render an honest degraded state instead of a false green when the
  GitHub fetch fails, and a degraded re-emit no longer blanks a rich card.
- Subagent identity reads as role + intent; the raw Codex agent path moves to a
  tooltip. Placeholder filler no longer stands in for a result summary.
- Real durations with an hour unit, formatted schedule times, wired card actions.

Proof
- Artifact paths resolve against the calling agent's lane worktree, and a
  missing file now throws instead of silently persisting an unrenderable record.
- Imports are gated on file type: the widened roots put .env.local, *.db and key
  material beside legitimate captures, and the store syncs to paired phones.
- Delete exists end to end: broker, IPC, action registry, ade proof rm/prune,
  drawer, and Settings storage. Artifacts carry lane_id and are removed with
  their lane; archive stays non-destructive.
- Proof renders inline where it was captured rather than pinned to the thread
  footer, with a per-turn chip into the drawer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Removing the pinned footer left computer-use proof with no inline
representation: the only proof_artifact card emitter is the Cursor Cloud
pull, so screenshots taken through capture/attach appeared nowhere in the
transcript.

The turn divider already grouped proof by capture time for its count chip;
it now carries the artifacts themselves and renders ChatProofFilmstrip
beneath the rule. The chip toggles it and starts collapsed, so a long
capture run never buries the reply, and "open all" still reaches the drawer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ent drops

The proof delete surface shipped unreachable. ade/actions/call dispatches off
READ_ONLY_TOOLS/MUTATION_TOOLS, and three registered tools were in neither, so
ade proof rm, prune --broken and recover all returned methodNotFound. Added
them, plus a test that fails without the fix.

Inline proof rendered no images: the filmstrip was mounted without a
resolveThumbnailSrc, so every tile showed its kind label. Local projects now
resolve previews through the ade-artifact:// project handler.

Security:
- Lane delete's unlink jail was a lexical prefix check. uri is CRR-replicated,
  so a peer can write it, and a directory symlink under the artifacts dir would
  let the unlink walk out. Now realpath-jailed like the broker's own resolver.
- The secrets deny-list compared lexically while the allow-list beside it
  realpaths, so a symlink into .ade/secrets passed the barrier it exists to be.

Correctness:
- artifact-deleted was emitted with owner: null, which every listener drops, so
  deletes made outside the drawer never refreshed it. Now emitted per owner.
- Batch ingest half-committed when one input was rejected; inputs resolve before
  any row is written.
- Restored heif/tif/tiff/m4v/ogv, which the CLI kind table and the preview MIME
  table already supported.
- browserMock lacked the four new methods, so the web renderer threw on delete.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@arul28
arul28 force-pushed the ade/couple-thigns-wanna-dsicuss-first-d432760f branch from 277be76 to 978f568 Compare July 28, 2026 23:30
@arul28

arul28 commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 978f568a69

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts Outdated
Comment thread apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts Outdated
@arul28

arul28 commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bcf580a96

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/services/prs/prChatCards.ts Outdated
Comment thread apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx (1)

138-147: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Broken timeline proof cards render nothing — isBrokenArtifact check is missing from ChatProofArtifactCard's ternary.

useVisibleArtifactPreview now early-returns for broken artifacts before ever setting loaded=true (Line 145: || isBrokenArtifact(artifact)). But the amber "broken" branch in ChatProofArtifactCard (Line 309) only triggers on mediaFailed || (loaded && !preview && (image || video)). Since loaded never becomes true for a broken artifact (no fetch is attempted) and no <img>/<video> is ever rendered to fire onError/set mediaFailed, none of the ternary branches match for a broken artifact — the card falls through to null and renders an empty body (just the header), for both image/video and generic-file broken artifacts alike.

This defeats the feature's own stated purpose ("We know exactly why a tile is blank, so say it" — Line 75) for the primary chat-timeline card; only DrawerProofTile, which checks isBrokenArtifact directly (Line 454), gets this right.

🐛 Proposed fix
-        ) : mediaFailed || (loaded && !preview && (image || video)) ? (
+        ) : mediaFailed || isBrokenArtifact(artifact) || (loaded && !preview && (image || video)) ? (

Also applies to: 305-319

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx` around
lines 138 - 147, Update the broken-artifact branch in ChatProofArtifactCard’s
rendering ternary to check isBrokenArtifact(artifact) directly, alongside the
existing mediaFailed and preview failure conditions. Ensure broken image, video,
and generic-file artifacts render the amber broken state instead of falling
through to null, while preserving the existing rendering behavior for non-broken
artifacts.
apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx (1)

7013-7024: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Non-virtualized rows never get resolveProofThumbnailSrc.

The virtualized branch passes turnProof, resolveProofThumbnailSrc, and onOpenProofDrawer (Lines 6970-6972), but this branch omits resolveProofThumbnailSrc. Short transcripts (below VIRTUALIZATION_THRESHOLD) therefore render every proof tile as a bare kind label instead of a thumbnail — which is exactly the common case for a fresh chat.

🐛 Proposed fix
         turnProof={turnProof}
+        resolveProofThumbnailSrc={resolveProofThumbnailSrc}
         onOpenProofDrawer={onOpenProofDrawer}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx` around
lines 7013 - 7024, Update the non-virtualized EventRow render path in
AgentChatMessageList to pass the existing resolveProofThumbnailSrc callback,
matching the virtualized branch alongside turnProof and onOpenProofDrawer.
Preserve all other row props and behavior.
apps/desktop/src/renderer/components/chat/codex/CodexPlanCard.tsx (1)

116-131: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Enter/Space on the markdown toggle also fires the card's onOpenInfo.

The toggle stops click propagation, but keydown still bubbles to the role="button" wrapper (Lines 59-65), which has no target !== currentTarget guard. Activating the toggle by keyboard therefore both expands the markdown and navigates to chat info. AdeCard.tsx guards this exact case at Lines 319-328 — mirror it here.

🐛 Proposed fix (outside the selected range, at Lines 59-65)
       onKeyDown={(keyboardEvent) => {
         if (!onOpenInfo) return;
+        // Nested controls handle their own keyboard activation; letting their
+        // Enter/Space bubble here would open info on top of the action.
+        if (keyboardEvent.target !== keyboardEvent.currentTarget) return;
         if (keyboardEvent.key === "Enter" || keyboardEvent.key === " ") {
           keyboardEvent.preventDefault();
           onOpenInfo();
         }
       }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/codex/CodexPlanCard.tsx` around
lines 116 - 131, Update the CodexPlanCard role="button" wrapper’s keyboard
handler near the card onOpenInfo logic to ignore events whose target differs
from currentTarget, matching AdeCard.tsx. Preserve keyboard activation for the
card itself while preventing Enter/Space on the markdown toggle from also
opening chat info.
🧹 Nitpick comments (8)
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts (2)

1200-1231: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Lane-owned-artifact SQL is duplicated in laneService.ts.

This predicate is byte-for-byte the LANE_OWNED_ARTIFACT_IDS_SQL constant in apps/desktop/src/main/services/lanes/laneService.ts (lines 180-200). Two copies of the same "which artifacts does a lane own" rule will drift; export it from one place and import it here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts`
around lines 1200 - 1231, Replace the duplicated lane-owned-artifact SQL inside
deleteArtifactsForLane with the exported LANE_OWNED_ARTIFACT_IDS_SQL from
laneService.ts, importing that constant through the existing service module
conventions. Preserve the current projectId and laneId parameter ordering and
delete behavior.

132-159: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Two stacked doc blocks on one function. The first block ("Paths an agent may read…") is orphaned above the second; merge them so the rationale reads as one comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts`
around lines 132 - 159, Merge the two consecutive documentation blocks above
isDeniedArtifactSource into a single comment, preserving both the security
description and the realpath rationale as one coherent explanation attached to
that function. Keep realpathOrSelf’s separate documentation unchanged.
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts (1)

432-437: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

rmSync mock throws when the candidate no longer exists. fs.realpathSync(String(candidate)) raises ENOENT for any path already gone, so the mock surfaces an unrelated error instead of delegating. Guard the realpath call (or compare path.resolve) so the spy stays inert for non-target paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts`
around lines 432 - 437, Update the rmSync spy setup to avoid calling
fs.realpathSync on candidates that may already be absent; compare normalized
paths safely, or guard realpathSync failures, so only canonicalFilePath triggers
the simulated EACCES error and all other candidates delegate to originalRmSync.
apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts (1)

1058-1095: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

The degraded/stale merge contract is implemented twice. Both copies are byte-for-byte the same algorithm, and both files already import from apps/desktop/src/shared/adeCard.ts — the contract's own module. Any future tweak (e.g. treating rowsTruncated as detail, or clearing actions differently) has to be made in two places or the two surfaces silently diverge.

  • apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts#L1058-L1095: replace the body of mergeAdeCardEvent with a call to a shared mergeAdeCardPayload exported from apps/desktop/src/shared/adeCard.ts, keeping the local cardId override.
  • apps/ade-cli/src/tuiClient/format.ts#L50-L79: delete the local mergeAdeCardPayload and import the shared one instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts` around lines
1058 - 1095, The degraded/stale merge algorithm is duplicated and must be
centralized. In
apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts:1058-1095,
replace mergeAdeCardEvent’s merge logic with the shared mergeAdeCardPayload from
apps/desktop/src/shared/adeCard.ts while preserving the local cardId override.
In apps/ade-cli/src/tuiClient/format.ts:50-79, remove the local
mergeAdeCardPayload implementation and import the shared function instead.
apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx (1)

539-547: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Destructive delete/prune actions have no confirmation step.

The per-tile delete button (Line 539-547) and the "Remove them" batch prune action (Line 673-679) both permanently remove artifact records with a single click and no confirmation — including for artifacts that are currently "available" (not broken). Given these are proof/evidence artifacts, an accidental click loses evidence with no undo path (unlike the broken-item "recover" flow, which is explicitly recoverable).

♻️ Suggested guard
   const handleDelete = useCallback(
     (artifact: ComputerUseArtifactView) => {
+      if (!window.confirm(`Delete "${artifact.title}"? This cannot be undone.`)) return;
       void withBusy([artifact.id], () =>
         window.ade.computerUse.deleteArtifacts({ artifactId: artifact.id }),
       );
     },
     [withBusy],
   );

Apply an analogous guard to handlePruneBroken for the batch case.

Also applies to: 668-681

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx` around
lines 539 - 547, 3Add confirmation guards to both destructive artifact-removal
paths: wrap the per-tile delete handler around the button invoking
onDelete(artifact), and add an analogous confirmation to handlePruneBroken
before batch removal. Require explicit confirmation for all artifacts, including
available ones, while preserving the existing removal behavior after
confirmation.
apps/desktop/src/renderer/components/chat/ChatWorkLogBlock.tsx (1)

685-695: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Expansion is one-way and aria-expanded is hardcoded.

Once showHistory flips true the button unmounts (hiddenCount becomes 0), so there is no way back to the folded view. Consider rendering the control whenever activityEntries.length > 1 and toggling both the state and aria-expanded.

♻️ Toggle instead of one-way expand
-      {hiddenCount > 0 ? (
+      {hiddenCount > 0 || showHistory ? (
         <button
           type="button"
-          onClick={() => setShowHistory(true)}
-          aria-expanded={false}
+          onClick={() => setShowHistory((open) => !open)}
+          aria-expanded={showHistory}
           className="flex items-center gap-1.5 px-1 py-0.5 font-sans text-[length:calc(var(--chat-font-size)*10.5/14)] text-fg/40 transition-colors hover:text-fg/70"
         >
           <CaretDown size={10} weight="bold" aria-hidden />
-          +{hiddenCount} previous tool call{hiddenCount === 1 ? "" : "s"}
+          {showHistory ? "Hide previous tool calls" : `+${hiddenCount} previous tool call${hiddenCount === 1 ? "" : "s"}`}
         </button>
       ) : null}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/ChatWorkLogBlock.tsx` around lines
685 - 695, Update the history control in ChatWorkLogBlock so it renders whenever
activityEntries.length is greater than one, including when history is expanded.
Change its click handler to toggle showHistory and bind aria-expanded to the
current showHistory value, while preserving the hidden-count label and
folded/expanded content behavior.
apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx (1)

6182-6212: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Bucketing rescans the full artifact list per done row.

stamped is sorted, so each window could advance a cursor instead of re-filtering all artifacts for every turn (O(dones × artifacts)). Fine at today's sizes; worth tightening if proof counts grow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx` around
lines 6182 - 6212, Optimize turnProofByRowKey by replacing the per-`done` row
`stamped.filter` scan with a forward-only cursor over the sorted artifacts.
Advance the cursor as artifacts fall before each window start, collect entries
through `endMs`, and preserve the existing inclusive first-window and exclusive
subsequent-window boundaries.
apps/desktop/src/renderer/components/chat/chatCardPrimitives.tsx (1)

419-447: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Thumbnail has no error fallback.

resolveThumbnailSrc can return a URL for an artifact whose bytes are gone (deleted file, unimported availability), and the tile then renders the browser's broken-image glyph instead of the kind label the null branch already provides. An onError that clears the src recovers the honest fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/chat/chatCardPrimitives.tsx` around
lines 419 - 447, The artifact thumbnail image rendered in the artifacts map
lacks an error fallback. Update the img element in the open artifacts block to
track and clear its source when loading fails, so failed URLs render the
existing kind-label fallback instead of a broken-image glyph; preserve the
current null-source behavior and styling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ade-cli/src/adeRpcServer.ts`:
- Around line 4398-4404: In the callerRoot resolution flow, derive the
authorized root from the server-authorized session lane and reject explicit
callerRoot or laneId values unless their canonical worktree path matches that
root; do not accept arbitrary absolute directories. Update
apps/ade-cli/src/adeRpcServer.ts lines 4398-4404 accordingly. In
apps/ade-cli/src/adeRpcServer.test.ts lines 1796-1828, replace the arbitrary
absolute-root success case with an authorized-lane case and add coverage
rejecting a different absolute root.

In `@apps/ade-cli/src/tuiClient/adeCardFormat.ts`:
- Around line 119-128: The row truncation display in the card formatting flow
must include rows removed by both the emitter and the local five-row cap. Update
the logic around rows and rowsTruncated in the card formatter to calculate the
residual rows beyond the displayed slice, then show +N more using rowsTruncated
plus that residual, matching the iOS card behavior.

In `@apps/desktop/src/main/services/adeActions/registry.ts`:
- Around line 803-814: Remove deleteArtifacts, recoverArtifact,
pruneBrokenArtifacts, and listBrokenArtifacts from the computer_use_artifacts
registry in apps/desktop/src/main/services/adeActions/registry.ts (lines
803-814) until the action boundary provides an authenticated owner scope. In
apps/ade-cli/src/adeRpcServer.ts (lines 4442-4470), derive the owner/principal
from the server authorization context and pass it into broker operations,
enforce that scope in broker queries, and permit project-wide pruning only for
an explicitly authorized maintenance role.

In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts`:
- Around line 889-922: Normalize artifact URIs to jailed filesystem paths before
determining whether another row shares the file. In
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts:889-922,
update the sharedReference logic around resolveArtifactFilePath to resolve
candidate rows and compare their paths with filePath instead of relying on raw
uri equality. In apps/desktop/src/main/services/lanes/laneService.ts:3070-3077,
replace the survivor.uri equality guard with the same resolved-path comparison,
using resolveRendererArtifactPath and resolvePathWithinRoot.

In `@apps/desktop/src/main/services/lanes/laneService.ts`:
- Around line 6299-6302: Update the lane artifact deletion flow around
removeLaneArtifactFiles so the helper returns the number of files successfully
removed, while preserving warning handling for failures. Use that success count
in the returned detail message, and return undefined when none were removed so
progress reports only completed deletions.

In `@apps/desktop/src/main/services/projects/adeProjectService.ts`:
- Around line 464-480: The packs cleanup in the options.packs block deletes all
project artifact records while removing only artifactsDir, including
attachment-backed records. Restrict the deletes in the artifact row cleanup to
artifacts owned by repair.paths.artifactsDir, or also remove the attachments
root before deleting those records; preserve attachment-backed records when
their files remain available.

In `@apps/desktop/src/renderer/browserMock.ts`:
- Around line 3756-3761: Update the deleteArtifacts and pruneBrokenArtifacts
mocks to include the required freedBytes field, and make recoverArtifact resolve
a contract-valid artifact view rather than an empty object. Remove the as any
casts and construct results using the production return types or established
valid mock values, preserving the existing list fields and resolvedArg behavior.

In `@apps/desktop/src/renderer/components/settings/StorageSection.tsx`:
- Around line 1507-1511: The blocked-state message in the cleanable storage
section should state the next action: direct users to the chat proof drawer to
delete individual proofs. Update the text within the cleanable.length === 0
branch while preserving its existing styling and conditional rendering.
- Around line 1496-1499: Update the title constructed in the onRequestCleanup
handler to preserve entry.item.label’s acronym casing; remove the full label
lowercasing or only lowercase its initial character if sentence case is
required, while leaving the rest of the cleanup dialog unchanged.

In `@apps/desktop/src/shared/types/computerUseArtifacts.ts`:
- Around line 174-186: The computer-use event fanout does not consume
broker-emitted artifact-deleted events, leaving stale drawer rows. Update the
existing computer-use event subscribers and renderer/TUI/iOS handlers to handle
artifact-deleted, refresh the proof drawer, and remove the corresponding
artifact row using the existing event payload and removal flow.

In `@apps/ios/ADE/Views/Work/WorkChatRichCardViews.swift`:
- Around line 4133-4137: Update hiddenRowCount for the card.variant == "pr_ci"
branch to include failure rows omitted by visibleRows after the existing
prefix(4) limit, while retaining card.rowsTruncated and excluding filtered-out
passing rows. Use the same failure-filtered candidate collection that
visibleRows derives from so the count reports all locally hidden failing rows.

In `@apps/ios/ADE/Views/Work/WorkEventMapping.swift`:
- Line 769: Update the payload mapping around degradedReason to trim whitespace
and convert blank values to nil before passing them into merging(_:), matching
the direct-transcript parser’s optionalString behavior while preserving
non-blank reasons.

---

Outside diff comments:
In `@apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx`:
- Around line 7013-7024: Update the non-virtualized EventRow render path in
AgentChatMessageList to pass the existing resolveProofThumbnailSrc callback,
matching the virtualized branch alongside turnProof and onOpenProofDrawer.
Preserve all other row props and behavior.

In `@apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx`:
- Around line 138-147: Update the broken-artifact branch in
ChatProofArtifactCard’s rendering ternary to check isBrokenArtifact(artifact)
directly, alongside the existing mediaFailed and preview failure conditions.
Ensure broken image, video, and generic-file artifacts render the amber broken
state instead of falling through to null, while preserving the existing
rendering behavior for non-broken artifacts.

In `@apps/desktop/src/renderer/components/chat/codex/CodexPlanCard.tsx`:
- Around line 116-131: Update the CodexPlanCard role="button" wrapper’s keyboard
handler near the card onOpenInfo logic to ignore events whose target differs
from currentTarget, matching AdeCard.tsx. Preserve keyboard activation for the
card itself while preventing Enter/Space on the markdown toggle from also
opening chat info.

---

Nitpick comments:
In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts`:
- Around line 432-437: Update the rmSync spy setup to avoid calling
fs.realpathSync on candidates that may already be absent; compare normalized
paths safely, or guard realpathSync failures, so only canonicalFilePath triggers
the simulated EACCES error and all other candidates delegate to originalRmSync.

In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts`:
- Around line 1200-1231: Replace the duplicated lane-owned-artifact SQL inside
deleteArtifactsForLane with the exported LANE_OWNED_ARTIFACT_IDS_SQL from
laneService.ts, importing that constant through the existing service module
conventions. Preserve the current projectId and laneId parameter ordering and
delete behavior.
- Around line 132-159: Merge the two consecutive documentation blocks above
isDeniedArtifactSource into a single comment, preserving both the security
description and the realpath rationale as one coherent explanation attached to
that function. Keep realpathOrSelf’s separate documentation unchanged.

In `@apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx`:
- Around line 6182-6212: Optimize turnProofByRowKey by replacing the per-`done`
row `stamped.filter` scan with a forward-only cursor over the sorted artifacts.
Advance the cursor as artifacts fall before each window start, collect entries
through `endMs`, and preserve the existing inclusive first-window and exclusive
subsequent-window boundaries.

In `@apps/desktop/src/renderer/components/chat/chatCardPrimitives.tsx`:
- Around line 419-447: The artifact thumbnail image rendered in the artifacts
map lacks an error fallback. Update the img element in the open artifacts block
to track and clear its source when loading fails, so failed URLs render the
existing kind-label fallback instead of a broken-image glyph; preserve the
current null-source behavior and styling.

In `@apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx`:
- Around line 539-547: 3Add confirmation guards to both destructive
artifact-removal paths: wrap the per-tile delete handler around the button
invoking onDelete(artifact), and add an analogous confirmation to
handlePruneBroken before batch removal. Require explicit confirmation for all
artifacts, including available ones, while preserving the existing removal
behavior after confirmation.

In `@apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts`:
- Around line 1058-1095: The degraded/stale merge algorithm is duplicated and
must be centralized. In
apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts:1058-1095,
replace mergeAdeCardEvent’s merge logic with the shared mergeAdeCardPayload from
apps/desktop/src/shared/adeCard.ts while preserving the local cardId override.
In apps/ade-cli/src/tuiClient/format.ts:50-79, remove the local
mergeAdeCardPayload implementation and import the shared function instead.

In `@apps/desktop/src/renderer/components/chat/ChatWorkLogBlock.tsx`:
- Around line 685-695: Update the history control in ChatWorkLogBlock so it
renders whenever activityEntries.length is greater than one, including when
history is expanded. Change its click handler to toggle showHistory and bind
aria-expanded to the current showHistory value, while preserving the
hidden-count label and folded/expanded content behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0390fb86-0e3d-45b4-855a-9f5c912be033

📥 Commits

Reviewing files that changed from the base of the PR and between 668fa9a and 4bcf580.

⛔ Files ignored due to path filters (15)
  • docs/ARCHITECTURE.md is excluded by !docs/**
  • docs/features/chat/README.md is excluded by !docs/**
  • docs/features/chat/composer-and-ui.md is excluded by !docs/**
  • docs/features/chat/tool-system.md is excluded by !docs/**
  • docs/features/chat/transcript-and-turns.md is excluded by !docs/**
  • docs/features/computer-use/README.md is excluded by !docs/**
  • docs/features/computer-use/artifact-broker.md is excluded by !docs/**
  • docs/features/computer-use/backends.md is excluded by !docs/**
  • docs/features/lanes/README.md is excluded by !docs/**
  • docs/features/lanes/worktree-isolation.md is excluded by !docs/**
  • docs/features/onboarding-and-settings/README.md is excluded by !docs/**
  • docs/features/proof.md is excluded by !docs/**
  • docs/features/pull-requests/README.md is excluded by !docs/**
  • docs/features/storage-and-recovery/README.md is excluded by !docs/**
  • docs/features/sync-and-multi-device/ios-companion.md is excluded by !docs/**
📒 Files selected for processing (66)
  • .gitleaksignore
  • apps/ade-cli/README.md
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/bootstrap.ts
  • apps/ade-cli/src/cli.test.ts
  • apps/ade-cli/src/cli.ts
  • apps/ade-cli/src/services/sync/syncHostService.test.ts
  • apps/ade-cli/src/services/sync/syncHostService.ts
  • apps/ade-cli/src/tuiClient/__tests__/format.test.ts
  • apps/ade-cli/src/tuiClient/adeCardFormat.ts
  • apps/ade-cli/src/tuiClient/format.ts
  • apps/desktop/src/main/main.ts
  • apps/desktop/src/main/services/adeActions/registry.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/main/services/computerUse/controlPlane.test.ts
  • apps/desktop/src/main/services/computerUse/controlPlane.ts
  • apps/desktop/src/main/services/ipc/registerIpc.ts
  • apps/desktop/src/main/services/lanes/laneService.test.ts
  • apps/desktop/src/main/services/lanes/laneService.ts
  • apps/desktop/src/main/services/projects/adeProjectService.ts
  • apps/desktop/src/main/services/proof/agentBrowserArtifactAdapter.test.ts
  • apps/desktop/src/main/services/proof/agentBrowserArtifactAdapter.ts
  • apps/desktop/src/main/services/prs/prChatCards.test.ts
  • apps/desktop/src/main/services/prs/prChatCards.ts
  • apps/desktop/src/main/services/state/kvDb.ts
  • apps/desktop/src/main/services/storage/storageInsightsService.test.ts
  • apps/desktop/src/main/services/storage/storageInsightsService.ts
  • apps/desktop/src/preload/global.d.ts
  • apps/desktop/src/preload/preload.ts
  • apps/desktop/src/renderer/browserMock.ts
  • apps/desktop/src/renderer/components/chat/AdeCard.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.test.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.test.tsx
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx
  • apps/desktop/src/renderer/components/chat/ChatFileChangesPanel.tsx
  • apps/desktop/src/renderer/components/chat/ChatWorkLogBlock.tsx
  • apps/desktop/src/renderer/components/chat/ContextCompactDivider.tsx
  • apps/desktop/src/renderer/components/chat/SubagentActivityCards.tsx
  • apps/desktop/src/renderer/components/chat/chatAppearance.ts
  • apps/desktop/src/renderer/components/chat/chatCardPrimitives.test.ts
  • apps/desktop/src/renderer/components/chat/chatCardPrimitives.tsx
  • apps/desktop/src/renderer/components/chat/chatTranscriptRows.test.ts
  • apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts
  • apps/desktop/src/renderer/components/chat/codex/CodexPlanCard.tsx
  • apps/desktop/src/renderer/components/settings/StorageSection.tsx
  • apps/desktop/src/renderer/components/settings/storage/storageView.ts
  • apps/desktop/src/renderer/lib/format.test.ts
  • apps/desktop/src/renderer/lib/format.ts
  • apps/desktop/src/shared/adeCard.ts
  • apps/desktop/src/shared/ipc.ts
  • apps/desktop/src/shared/types/computerUseArtifacts.ts
  • apps/desktop/src/shared/types/storage.ts
  • apps/ios/ADE/Models/RemoteModels.swift
  • apps/ios/ADE/Resources/DatabaseBootstrap.sql
  • apps/ios/ADE/Services/Database.swift
  • apps/ios/ADE/Views/Work/WorkArtifactTerminalViews.swift
  • apps/ios/ADE/Views/Work/WorkChatRichCardViews.swift
  • apps/ios/ADE/Views/Work/WorkErrorAndMessageHelpers.swift
  • apps/ios/ADE/Views/Work/WorkEventMapping.swift
  • apps/ios/ADE/Views/Work/WorkModels.swift
  • apps/ios/ADE/Views/Work/WorkTranscriptParser.swift
  • apps/ios/ADETests/ADETests.swift
💤 Files with no reviewable changes (2)
  • apps/desktop/src/main/services/proof/agentBrowserArtifactAdapter.ts
  • apps/desktop/src/main/services/proof/agentBrowserArtifactAdapter.test.ts

Comment thread apps/ade-cli/src/adeRpcServer.ts Outdated
Comment thread apps/ade-cli/src/tuiClient/adeCardFormat.ts Outdated
Comment thread apps/desktop/src/main/services/adeActions/registry.ts
Comment thread apps/desktop/src/main/services/lanes/laneService.ts Outdated
Comment thread apps/desktop/src/renderer/components/settings/StorageSection.tsx
Comment thread apps/desktop/src/renderer/components/settings/StorageSection.tsx
Comment thread apps/desktop/src/shared/types/computerUseArtifacts.ts
Comment thread apps/ios/ADE/Views/Work/WorkChatRichCardViews.swift Outdated
Comment thread apps/ios/ADE/Views/Work/WorkEventMapping.swift Outdated
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ae00206e1

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/adeRpcServer.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
apps/desktop/src/renderer/components/settings/StorageSection.test.tsx (1)

373-390: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Brittle DOM traversal and two scenarios in one test.

parentElement!.parentElement!.parentElement! breaks on any wrapper change — prefer closest(...) on a stable selector or a role-based container query. Splitting the pre-cleanup() casing assertion and the blocked-cleanup assertion into two it blocks would also isolate failures.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/settings/StorageSection.test.tsx` around
lines 373 - 390, Refactor the test around the proof cleanup flow into two
independent it blocks: one covering ADE casing and proof-drawer navigation, and
another covering blocked cleanup. In the first block, replace the chained
parentElement traversal used to locate proofRow with a stable closest selector
or role-based container query, while preserving the existing assertions and
cleanup behavior.
apps/ade-cli/src/adeRpcServer.ts (1)

4625-4664: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Per-entry ownership lookups are O(N) broker queries.

Both list_broken_computer_use_artifacts and prune_broken_computer_use_artifacts call listArtifacts({ artifactId }) once per broken entry with a 2000-row ceiling. Fetch the caller's owned artifacts once (via listArtifacts per authorized owner) and match against that set instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ade-cli/src/adeRpcServer.ts` around lines 4625 - 4664, Replace the
per-entry listArtifacts calls in both list_broken_computer_use_artifacts and
prune_broken_computer_use_artifacts with one fetched ownership set: call
listArtifacts once for each authorized owner from resolveAuthorizedProofOwners,
then match broken entries against those results by artifact ID. Preserve the
existing authorization checks, requestedLimit behavior, and prune deletion
results while avoiding O(N) broker queries.
apps/ade-cli/src/adeRpcServer.test.ts (1)

1310-1318: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

recoverArtifact/pruneBrokenArtifacts/listBrokenArtifacts scoping is mocked but never exercised.

The test name promises coverage of "proof lifecycle tools" scoping, but only ingest/list/delete are actually invoked and asserted; the recover/prune/broken-listing mocks are set up and never called. Consider adding assertions (or dropping the unused mocks) so the test title matches its actual coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ade-cli/src/adeRpcServer.test.ts` around lines 1310 - 1318, Update the
proof lifecycle tools test around the computerUseArtifactBrokerService mocks to
either invoke and assert recoverArtifact, pruneBrokenArtifacts, and
listBrokenArtifacts with the expected scoping, or remove their unused mock
setup. Keep the test title aligned with the lifecycle operations it actually
covers.
apps/desktop/src/main/services/lanes/laneService.test.ts (1)

3373-3379: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Symlink mismatch could make the rmSync mock never fire on macOS.

The spy compares path.resolve(String(candidate)) against fs.realpathSync(failedFile). Since repoRoot is derived from os.mkdtempSync(path.join(os.tmpdir(), ...)), and os.tmpdir() resolves to a symlink on macOS (/var/folders/... vs. real /private/var/folders/...), candidate (built off the non-realpath’d repoRoot) may never equal fs.realpathSync(failedFile) on such machines, so the mocked failure never triggers and the "partial failure" assertion is unreliable outside of symlink-free environments.

🐛 Proposed fix: normalize both sides the same way
-      if (path.resolve(String(candidate)) === fs.realpathSync(failedFile)) {
+      if (fs.realpathSync(path.resolve(String(candidate))) === fs.realpathSync(failedFile)) {
         throw Object.assign(new Error("permission denied"), { code: "EACCES" });
       }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/main/services/lanes/laneService.test.ts` around lines 3373 -
3379, Update the rmSync spy in the partial-failure test to normalize both the
candidate path and failedFile using the same path representation before
comparing them, such as resolving each consistently without mixing
symlink-preserving and real paths. Keep the EACCES throw behavior and
originalRmSync fallback unchanged so the failure reliably triggers on macOS and
other symlinked temporary-directory environments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ade-cli/src/adeRpcServer.ts`:
- Around line 4571-4589: The scoped artifact-listing path in the
!projectWideAuthorized branch must sort the merged artifacts by createdAt
descending before applying the limit. Update the artifacts collection handling
around runtime.computerUseArtifactBrokerService.listArtifacts so deduplication
is preserved, then sort [...artifacts.values()] consistently with the
project-wide ordering and only afterward call slice(0, limit).

---

Nitpick comments:
In `@apps/ade-cli/src/adeRpcServer.test.ts`:
- Around line 1310-1318: Update the proof lifecycle tools test around the
computerUseArtifactBrokerService mocks to either invoke and assert
recoverArtifact, pruneBrokenArtifacts, and listBrokenArtifacts with the expected
scoping, or remove their unused mock setup. Keep the test title aligned with the
lifecycle operations it actually covers.

In `@apps/ade-cli/src/adeRpcServer.ts`:
- Around line 4625-4664: Replace the per-entry listArtifacts calls in both
list_broken_computer_use_artifacts and prune_broken_computer_use_artifacts with
one fetched ownership set: call listArtifacts once for each authorized owner
from resolveAuthorizedProofOwners, then match broken entries against those
results by artifact ID. Preserve the existing authorization checks,
requestedLimit behavior, and prune deletion results while avoiding O(N) broker
queries.

In `@apps/desktop/src/main/services/lanes/laneService.test.ts`:
- Around line 3373-3379: Update the rmSync spy in the partial-failure test to
normalize both the candidate path and failedFile using the same path
representation before comparing them, such as resolving each consistently
without mixing symlink-preserving and real paths. Keep the EACCES throw behavior
and originalRmSync fallback unchanged so the failure reliably triggers on macOS
and other symlinked temporary-directory environments.

In `@apps/desktop/src/renderer/components/settings/StorageSection.test.tsx`:
- Around line 373-390: Refactor the test around the proof cleanup flow into two
independent it blocks: one covering ADE casing and proof-drawer navigation, and
another covering blocked cleanup. In the first block, replace the chained
parentElement traversal used to locate proofRow with a stable closest selector
or role-based container query, while preserving the existing assertions and
cleanup behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f53dfe9c-9a73-4eb0-9d9a-9af9575f2f70

📥 Commits

Reviewing files that changed from the base of the PR and between 4bcf580 and 1ae0020.

📒 Files selected for processing (30)
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/ade-cli/src/tuiClient/__tests__/format.test.ts
  • apps/ade-cli/src/tuiClient/adeCardFormat.ts
  • apps/desktop/src/main/services/adeActions/registry.test.ts
  • apps/desktop/src/main/services/adeActions/registry.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/main/services/lanes/laneService.test.ts
  • apps/desktop/src/main/services/lanes/laneService.ts
  • apps/desktop/src/main/services/projects/adeProjectService.ts
  • apps/desktop/src/main/services/projects/projectLifecycle.test.ts
  • apps/desktop/src/main/services/prs/prChatCards.test.ts
  • apps/desktop/src/main/services/prs/prChatCards.ts
  • apps/desktop/src/main/services/storage/storageInsightsService.test.ts
  • apps/desktop/src/main/services/storage/storageInsightsService.ts
  • apps/desktop/src/renderer/browserMock.test.ts
  • apps/desktop/src/renderer/browserMock.ts
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.test.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.test.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/desktop/src/renderer/components/chat/chatCardPrimitives.tsx
  • apps/desktop/src/renderer/components/chat/codex/CodexPlanCard.test.tsx
  • apps/desktop/src/renderer/components/chat/codex/CodexPlanCard.tsx
  • apps/desktop/src/renderer/components/settings/StorageSection.test.tsx
  • apps/desktop/src/renderer/components/settings/StorageSection.tsx
  • apps/ios/ADE/Views/Work/WorkChatRichCardViews.swift
  • apps/ios/ADE/Views/Work/WorkEventMapping.swift
  • apps/ios/ADETests/ADETests.swift
🚧 Files skipped from review as they are similar to previous changes (17)
  • apps/desktop/src/renderer/browserMock.ts
  • apps/ios/ADE/Views/Work/WorkEventMapping.swift
  • apps/desktop/src/renderer/components/chat/codex/CodexPlanCard.tsx
  • apps/desktop/src/renderer/components/settings/StorageSection.tsx
  • apps/desktop/src/renderer/components/chat/AgentChatPane.tsx
  • apps/ade-cli/src/tuiClient/tests/format.test.ts
  • apps/ios/ADETests/ADETests.swift
  • apps/desktop/src/main/services/projects/adeProjectService.ts
  • apps/desktop/src/main/services/storage/storageInsightsService.ts
  • apps/desktop/src/main/services/lanes/laneService.ts
  • apps/desktop/src/main/services/prs/prChatCards.ts
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.test.tsx
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts
  • apps/ade-cli/src/tuiClient/adeCardFormat.ts
  • apps/desktop/src/renderer/components/chat/chatCardPrimitives.tsx
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/renderer/components/chat/AgentChatMessageList.tsx

Comment thread apps/ade-cli/src/adeRpcServer.ts
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Addressed the current-head review batch in a5c01b413 and 8f17794c6:

  • restored broker-approved absolute proof sources while preserving the cross-lane worktree boundary
  • sorted the scoped proof union before applying its limit
  • replaced per-broken-entry ownership lookups with bounded per-owner queries
  • exercised scoped broken-list, prune, and recovery behavior
  • split the storage cleanup assertions and replaced parent-chain traversal with semantic card lookup

I did not change the lane deletion test: production passes rmSync the output of resolvePathWithinRoot, so the candidate is already realpath-normalized and the /var vs /private/var mismatch does not apply.

Validation: 183 focused tests pass; desktop and ADE CLI typechecks pass on Node 22.

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8f17794c6e

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx Outdated
Comment thread apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx Outdated
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Addressed the two current-head Codex P2 findings in c21168c50:

  • preview failures now distinguish intact stored proof from an explicitly missing file
  • successful RPC responses with failed delete outcomes now surface their reasons for both single delete and bulk prune
  • fixed the loading-state race that otherwise left null/failed previews spinning forever

Validation: 12 focused drawer tests and desktop typecheck pass on Node 22.

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c21168c50a

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Addressed the drawer-specific preview-state finding in ca6a80326:

  • production DrawerProofTile now distinguishes stored-file loss from intact-but-unpreviewable media
  • null previews and media decode failures render the compact warning explanation
  • only genuinely missing/unimported proof is counted as broken or offered recovery
  • moved the regression from the unused timeline helper to ChatComputerUsePanel itself

Validation: 12 focused drawer tests and desktop typecheck pass on Node 22.

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca6a80326d

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/adeRpcServer.ts
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts (1)

344-345: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert copied proof bytes in both attached-lane tests.

Availability and file existence also pass for a truncated or incorrect copy. Assert that the stored file equals the fixture buffer.

  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts#L344-L345: read ingested.artifacts[0]!.uri from projectRoot and compare it to the PNG buffer.
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts#L747-L749: compare the recovered file’s contents to the PNG buffer.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts`
around lines 344 - 345, Strengthen both attached-lane tests by reading the
stored artifact file and asserting its contents equal the fixture PNG buffer. At
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts:344-345,
resolve ingested.artifacts[0]!.uri from projectRoot and compare the bytes; apply
the same content comparison to the recovered file at :747-749.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts`:
- Around line 344-345: Strengthen both attached-lane tests by reading the stored
artifact file and asserting its contents equal the fixture PNG buffer. At
apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts:344-345,
resolve ingested.artifacts[0]!.uri from projectRoot and compare the bytes; apply
the same content comparison to the recovered file at :747-749.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b7353e42-dece-49dc-bf5d-1e66fe97214e

📥 Commits

Reviewing files that changed from the base of the PR and between 1ae0020 and 1da24f8.

📒 Files selected for processing (7)
  • apps/ade-cli/src/adeRpcServer.test.ts
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.test.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.test.tsx
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx
  • apps/desktop/src/renderer/components/settings/StorageSection.test.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/ade-cli/src/adeRpcServer.ts
  • apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts
  • apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1da24f8176

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/adeRpcServer.ts
Comment thread apps/desktop/src/main/services/storage/storageInsightsService.ts Outdated
Comment thread apps/desktop/src/renderer/components/chat/chatTranscriptRows.ts Outdated
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8483c7c433

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/services/computerUse/computerUseArtifactBrokerService.ts Outdated
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5971a1e130

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/ade-cli/src/adeRpcServer.ts
Comment thread apps/desktop/src/renderer/components/chat/ChatComputerUsePanel.tsx Outdated
@arul28

arul28 commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8f2fc2f8a

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
throw error;
}
const artifacts = resolved.map(({ input, kind, title, stored }) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make proof batch persistence atomic

If a later record or owner-link insert fails—for example because SQLite runs out of space or a sync trigger rejects a write—the earlier iterations of this map have already committed records and emitted events, while every staged file remains on disk. The RPC then reports failure, so retrying can duplicate the successfully persisted prefix and a link failure can leave proof without its required ownership. Wrap all record/link inserts in one transaction, remove newly staged files on rollback, and emit events only after commit.

AGENTS.md reference: AGENTS.md:L36-L36

Useful? React with 👍 / 👎.

Comment on lines +62 to +65
if (existingHadDetail && (!incomingHasDetail || incoming.degradedReason)) {
if (!incomingRows.length && existing.rows?.length) merged.rows = existing.rows;
if (!incomingMetrics.length && existing.metrics?.length) merged.metrics = existing.metrics;
if (incomingProgressTotal === 0 && existing.progress) merged.progress = existing.progress;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear stale card details on healthy empty refreshes

When a healthy full refresh explicitly reports no rows, metrics, or progress—for example after a PR's checks are removed—incomingHasDetail is false, so this branch preserves the previous job list and marks it stale instead of clearing it. It also prevents a recovery from clearing an old degraded reason and Retry action. Detect whether the detail fields were supplied, as the desktop merge does, rather than whether their totals are nonzero; the same value-based predicate in apps/ios/ADE/Views/Work/WorkModels.swift has the same stale-card behavior.

Useful? React with 👍 / 👎.

Comment on lines +2126 to +2129
if (!projectWideAuthorized && requestedLaneId && requestedLaneId !== sessionLaneId) {
throw new JsonRpcError(
JsonRpcErrorCode.invalidParams,
"laneId must match the caller's authorized chat-session lane",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow standalone ADE CLI callers to select a lane

A direct ade proof ingest --input-json call is initialized as an unbound ade-cli:<pid> agent, so it has no sessionLaneId; supplying the tool's documented laneId therefore always trips this check, even when callerRoot is inside that exact lane. The later inference path explicitly trusts these standalone CLI callers, but it is skipped whenever laneId is present, making explicit lane-scoped ingestion unusable through the desktop socket-backed RPC path. Permit an unbound ADE CLI caller here and validate the requested lane/root through laneService.

AGENTS.md reference: AGENTS.md:L35-L35

Useful? React with 👍 / 👎.

@arul28
arul28 merged commit 9427b37 into main Jul 29, 2026
33 checks passed
@arul28
arul28 deleted the ade/couple-thigns-wanna-dsicuss-first-d432760f branch July 29, 2026 04:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant