Fix integration writeback mounts and delivery confirmation#96
Conversation
|
CodeAnt AI is reviewing your PR. |
|
Warning Review limit reached
More reviews will be available in 10 minutes and 50 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (11)
📝 WalkthroughWalkthroughThis PR adds a message delivery confirmation flow across the broker and integration systems, derives local watch roots from integration globs, updates integration messaging, schedules per-project agent refresh timers on broker events, and improves symlink idempotency for concurrent safety. ChangesMessage Delivery Confirmation and Integration Synchronization
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a mechanism to wait for message delivery confirmation via sendMessageAndWaitForDelivery across several managers, handles token expiration gracefully by refreshing cloud authentication upon encountering unauthorized errors during workspace operations, and refines the mounting logic and documentation for integrations. The feedback highlights a critical compilation error due to a duplicate isRecord declaration in broker.ts, suggests simplifying deliveryFailureMessage using existing helpers, and recommends removing unnecessary as const assertions on message input objects to avoid strict TypeScript type-checking issues.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| function isRecord(value: unknown): value is Record<string, unknown> { | ||
| return typeof value === 'object' && value !== null | ||
| } |
| function deliveryFailureMessage(event: BrokerEvent): string { | ||
| if (!isRecord(event)) return 'Broker delivery failed' | ||
| const reason = typeof event.reason === 'string' ? event.reason : undefined | ||
| const lastError = typeof event.lastError === 'string' ? event.lastError : undefined | ||
| return reason || lastError || 'Broker delivery failed' | ||
| } |
There was a problem hiding this comment.
Simplify deliveryFailureMessage by reusing the existing brokerEventString helper. This avoids direct property access on the BrokerEvent union type (which can cause compilation errors depending on the TypeScript configuration) and removes the need for the local isRecord check.
function deliveryFailureMessage(event: BrokerEvent): string {
const reason = brokerEventString(event, 'reason')
const lastError = brokerEventString(event, 'lastError')
return reason || lastError || 'Broker delivery failed'
}| const input = { | ||
| to: agent.name, | ||
| from: options.from || 'system', | ||
| text: message, | ||
| priority: 0, | ||
| mode: 'steer', | ||
| data: options.data || { | ||
| kind: 'integrations-update', | ||
| system: true | ||
| } | ||
| } as const |
There was a problem hiding this comment.
Remove the as const assertion on the input object. Using as const infers all properties as readonly, which can cause strict type-checking errors when passed to functions expecting mutable types (like Record<string, unknown> for the data field). Since the type is already compatible, as const is unnecessary.
| const input = { | |
| to: agent.name, | |
| from: options.from || 'system', | |
| text: message, | |
| priority: 0, | |
| mode: 'steer', | |
| data: options.data || { | |
| kind: 'integrations-update', | |
| system: true | |
| } | |
| } as const | |
| const input = { | |
| to: agent.name, | |
| from: options.from || 'system', | |
| text: message, | |
| priority: 0, | |
| mode: 'steer', | |
| data: options.data || { | |
| kind: 'integrations-update', | |
| system: true | |
| } | |
| } |
| const input = { | ||
| to: recipient, | ||
| from: 'integration', | ||
| text: formatIntegrationEventMessage(event), | ||
| priority: 0, | ||
| mode: 'steer', | ||
| data: { | ||
| kind: 'integration-event', | ||
| system: true, | ||
| eventId: event.id, | ||
| eventType: event.type, | ||
| occurredAt: event.occurredAt, | ||
| resource: isRecord(event.resource) ? { ...event.resource } : undefined, | ||
| path: event.resource.path | ||
| } | ||
| } as const |
There was a problem hiding this comment.
Remove the as const assertion on the input object to prevent potential strict type-checking errors with readonly properties when passed to sendMessage or sendMessageAndWaitForDelivery.
| const input = { | |
| to: recipient, | |
| from: 'integration', | |
| text: formatIntegrationEventMessage(event), | |
| priority: 0, | |
| mode: 'steer', | |
| data: { | |
| kind: 'integration-event', | |
| system: true, | |
| eventId: event.id, | |
| eventType: event.type, | |
| occurredAt: event.occurredAt, | |
| resource: isRecord(event.resource) ? { ...event.resource } : undefined, | |
| path: event.resource.path | |
| } | |
| } as const | |
| const input = { | |
| to: recipient, | |
| from: 'integration', | |
| text: formatIntegrationEventMessage(event), | |
| priority: 0, | |
| mode: 'steer', | |
| data: { | |
| kind: 'integration-event', | |
| system: true, | |
| eventId: event.id, | |
| eventType: event.type, | |
| occurredAt: event.occurredAt, | |
| resource: isRecord(event.resource) ? { ...event.resource } : undefined, | |
| path: event.resource.path | |
| } | |
| } |
| const input = { | ||
| to: agent.name, | ||
| from: 'system', | ||
| text: message, | ||
| priority: 0, | ||
| mode: 'steer', | ||
| data: { | ||
| kind: 'integrations-update', | ||
| system: true | ||
| } | ||
| } as const |
There was a problem hiding this comment.
Remove the as const assertion on the input object to avoid potential strict type-checking issues with readonly properties.
| const input = { | |
| to: agent.name, | |
| from: 'system', | |
| text: message, | |
| priority: 0, | |
| mode: 'steer', | |
| data: { | |
| kind: 'integrations-update', | |
| system: true | |
| } | |
| } as const | |
| const input = { | |
| to: agent.name, | |
| from: 'system', | |
| text: message, | |
| priority: 0, | |
| mode: 'steer', | |
| data: { | |
| kind: 'integrations-update', | |
| system: true | |
| } | |
| } |
e3582cc to
795456a
Compare
| if (this.deps.getWorkspaceHandle) return this.deps.getWorkspaceHandle() | ||
| const { accountWorkspaceReadyRetryOptions, getAccountWorkspaceId, resolveCloudAuth } = await import('./auth.ts') | ||
| const auth = await resolveCloudAuth() | ||
| const { accountWorkspaceReadyRetryOptions, getAccountWorkspaceId, refreshCloudAuth, resolveCloudAuth } = await import('./auth.ts') |
There was a problem hiding this comment.
Suggestion: The dynamic import uses a .ts extension, which can break at runtime after transpilation/packaging when only .js files exist. Use the same extensionless module specifier pattern used elsewhere so the runtime resolver works in built artifacts. [import error]
Severity Level: Critical 🚨
- ❌ Local integration mount daemon fails during app startup.
- ❌ Integration event subscriptions fail to initialize for projects.
- ⚠️ Integration-event-based system messages never reach connected agents.Steps of Reproduction ✅
1. Build and run the production Electron app so the main process executes the compiled
`src/main/index.ts` entrypoint (importing `integrationsManager` from
`src/main/integrations.ts:8`).
2. When the app's `app.whenReady()` handler runs (`src/main/index.ts:5-25`), it calls
`integrationsManager.startLocalMountDaemon()` at `src/main/index.ts:25`.
3. `startLocalMountDaemon()` in `src/main/integrations.ts:12-15` calls
`this.syncAllEventSubscriptions()`, which in turn calls
`this.syncEventSubscriptions(projectId)` for each project
(`src/main/integrations.ts:19-24`), and `syncEventSubscriptions()` invokes
`integrationEventBridge.reconcile(projectId, …)` at `src/main/integrations.ts:21-23`.
4. `IntegrationEventBridge.reconcile()` calls `const handle = await
this.getWorkspaceHandle()` at `src/main/integration-event-bridge.ts:20`, which executes
`const { … } = await import('./auth.ts')` at `src/main/integration-event-bridge.ts:33`; in
a compiled/bundled build only `auth.js` (not `auth.ts`) exists next to the compiled file,
so the dynamic import for `'./auth.ts'` fails module resolution with a `Cannot find module
'./auth.ts'` error, preventing integration event subscriptions from being established.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/main/integration-event-bridge.ts
**Line:** 962:962
**Comment:**
*Import Error: The dynamic import uses a `.ts` extension, which can break at runtime after transpilation/packaging when only `.js` files exist. Use the same extensionless module specifier pattern used elsewhere so the runtime resolver works in built artifacts.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix|
CodeAnt AI finished reviewing your PR. |
|
Implemented fixes for PR #96. Key changes:
Local verification passed:
|
795456a to
248569b
Compare
|
Fixed the PR issues I found. Changes made:
Local validation passed:
|
|
Fixed the PR issues I found. Changes made:
Local validation passed:
|
248569b to
7e0c76a
Compare
|
Reviewed the checked-out PR diff and current workspace. Note: Validated/fixed state:
Verification run:
Could not complete full build locally:
I am not printing |
7e0c76a to
6bab112
Compare
|
Fixed two validated PR issues:
Local verification passed:
|
|
✅ pr-reviewer applied fixes — committed and pushed Fixed two validated PR issues:
Local verification passed:
|
|
Fixed the validated PR issues in the current checkout:
Verification passed:
|
|
Fixed the validated PR issues in the current checkout:
Verification passed:
|
User description
Summary
Validation
CodeAnt-AI Description
Fix integration writeback paths, delivery confirmation, and mount recovery after auth refresh
What Changed
Impact
✅ Fewer failed integration writebacks✅ Clearer file locations for connected integrations✅ Fewer missed integration and event messages✅ Less manual recovery after expired cloud auth🔄 Retrigger CodeAnt AI Review
💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.