-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Build a local takeover MVP #8270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 issues found across 12 files
Prompt for AI agents (all 3 issues)
Understand the root cause of the following 3 issues and fix them.
<file name="gui/src/components/BackgroundMode/BackgroundModeView.tsx">
<violation number="1" location="gui/src/components/BackgroundMode/BackgroundModeView.tsx:58">
`listBackgroundAgents` is invoked without the current organization, so in an org without GitHub integration this check silently succeeds and the GitHub setup prompt never appears. Please pass the active org ID (as in AgentsList) so the API can surface the auth error.</violation>
<violation number="2" location="gui/src/components/BackgroundMode/BackgroundModeView.tsx:87">
Include `currentOrg` in this effect’s dependency array; otherwise switching orgs leaves the GitHub warning stale (the check never re-runs for the new org).</violation>
</file>
<file name="gui/src/components/BackgroundMode/AgentsList.tsx">
<violation number="1" location="gui/src/components/BackgroundMode/AgentsList.tsx:37">
SSH-formatted repo URLs (e.g. ssh://git@github.com/owner/repo.git) are rewritten to https://github.com/ssh://…, so background agents created with SSH remotes never match the open workspace and the “Open locally” action stays disabled.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No issues found across 1 file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No issues found across 1 file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No issues found across 2 files
|
|
✅ Review Complete This is a review request for a PR that builds a local takeover MVP for background agents. Let me analyze the code changes: Code Review for PR #8270: Build a local takeover MVPCritical Issues1. Security: Missing Input Validation (Lines 270-290 in VsCodeMessenger.ts) const prompt = stripImages(content);
if (!prompt || prompt.trim().length === 0) {
vscode.window.showErrorMessage(...);
return;
}The Suggestion: Validate and sanitize these inputs: // Validate contextItems
const sanitizedContextItems = contextItems?.map(item => ({
content: sanitizeString(item.content),
description: sanitizeString(item.description),
name: sanitizeString(item.name),
uri: sanitizeString(item.uri)
})) || [];2. Race Condition: Branch Checkout (Lines 305-360 in VsCodeMessenger.ts) await repo.checkout(branch);If another VS Code window has the same repo open, git operations can conflict. No locking mechanism prevents concurrent modifications. Suggestion: Add a workspace-level lock or warn users about multiple windows. 3. Error Handling: Silent Failures (Lines 445-470 in client.ts) public async listBackgroundAgents(...): Promise<...> {
if (!(await this.isSignedIn())) {
return { agents: [], totalCount: 0 }; // Silent failure
}Returns empty arrays instead of throwing errors, making it impossible for callers to distinguish between "no agents" vs "API failed". Suggestion: Return a result type with error information: return { agents: [], totalCount: 0, error: "Not signed in" };Security Vulnerabilities4. Unvalidated Repository URLs (Lines 286-308 in VsCodeMessenger.ts) if (repoName.includes("/") && !repoName.startsWith("http")) {
repoUrl = `https://github.com/${repoName}`;
}This could allow injection if Suggestion: Use URL validation library or regex to ensure format is correct. 5. Stash Command Injection Risk (Line 295 in VsCodeMessenger.ts) await this.ide.subprocess(
`git stash push -m "Continue: Stashed before opening agent ${agentSessionId}"`,
workspacePath,
);If Suggestion: Use parameterized command execution or escape the ID: const escapedId = agentSessionId.replace(/[^a-zA-Z0-9-]/g, '');Functionality Issues6. Missing Error Recovery: Checkout Failure (Lines 315-355 in VsCodeMessenger.ts) Suggestion: Add rollback logic: const originalBranch = await this.ide.getBranch(matchingWorkspace);
try {
await repo.checkout(branch);
} catch (e) {
await repo.checkout(originalBranch); // Restore original state
throw e;
}7. Incomplete URL Normalization (Lines 172-210 in VsCodeMessenger.ts) Suggestion: Add support for other common Git hosts or make normalization more generic. 8. Missing Null Check (Line 367 in VsCodeMessenger.ts) if (!agentState.session) {
console.error("Agent state is missing session field...");
return;
}But Performance Issues9. Polling Without Backoff (Lines 136-143 in AgentsList.tsx) const interval = setInterval(() => {
void fetchAgents();
}, 10000);Polling every 10 seconds regardless of server load or errors. This could overwhelm the API or drain resources. Suggestion: Add exponential backoff on errors and consider WebSocket for real-time updates. 10. Redundant Workspace Fetching (Lines 70-95 in AgentsList.tsx) Missing Tests11. No Tests for Critical Flows
None of these have unit tests. This is risky for mission-critical functionality. Suggestion: Add tests for:
Documentation Issues12. Missing API Documentation (Lines 448-503 in client.ts)
Suggestion: Expand JSDoc with examples and error cases. Minor Issues13. Inconsistent Error Logging (Line 432 in client.ts) 14. Magic Numbers (Line 334 in VsCodeMessenger.ts) 15. Unused Variable (Line 69 in VsCodeMessenger.ts) Overall AssessmentThe feature implementation is ambitious and well-structured, but has significant security and reliability issues that must be addressed before merging. The main concerns are:
Recommendation: Request changes to address security issues (#1, #4, #5) and critical error handling (#3, #6, #8) before merging. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
continue/gui/src/components/mainInput/TipTapEditor/utils/resolveEditorContent.ts
Lines 148 to 175 in ce88f9a
| const isInAgentMode = getState().session.mode === "agent"; | |
| // Process context item attributes | |
| for (const item of deduplicatedInputs) { | |
| const result = await ideMessenger.request("context/getContextItems", { | |
| name: item.provider, | |
| query: item.query ?? "", | |
| fullInput: stripImages(parts), | |
| selectedCode, | |
| isInAgentMode, | |
| }); | |
| if (result.status === "success") { | |
| contextItems.push(...result.content); | |
| } | |
| } | |
| // cmd+enter to use codebase | |
| if ( | |
| modifiers.useCodebase && | |
| !deduplicatedInputs.some((item) => item.provider === "codebase") | |
| ) { | |
| const result = await ideMessenger.request("context/getContextItems", { | |
| name: "codebase", | |
| query: "", | |
| fullInput: stripImages(parts), | |
| selectedCode, | |
| isInAgentMode, | |
| }); |
When background mode is triggered, Chat.sendInput still calls resolveEditorContent to collect selected code and context before the agent is created. Inside resolveEditorContent the isInAgentMode flag is only set when state.session.mode === "agent", so background submissions are treated like plain chat (isInAgentMode is false). Any context providers that rely on this flag (e.g. codebase retrieval) won’t run in background mode, meaning the newly created background agents receive no context items or selected code despite the feature description saying they should. Consider treating "background" the same as "agent" here so background agents start with the same context as agent mode.
ℹ️ 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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 issues found across 12 files
Prompt for AI agents (all 2 issues)
Understand the root cause of the following 2 issues and fix them.
<file name="extensions/vscode/src/extension/VsCodeMessenger.ts">
<violation number="1" location="extensions/vscode/src/extension/VsCodeMessenger.ts:300">
SSH remotes are converted to invalid GitHub URLs (`https://github.com/git@github.com:owner/repo`), so creating a background agent fails for the common SSH setup.</violation>
</file>
<file name="gui/src/components/BackgroundMode/AgentsList.tsx">
<violation number="1" location="gui/src/components/BackgroundMode/AgentsList.tsx:241">
If createdAt is absent or invalid, formatRelativeTime returns "NaNd ago" because Math.floor(NaN) propagates through the template; add an explicit NaN guard so we fall back to the raw date string instead of showing garbage.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed changes from recent commits (found 1 issue).
1 issue found across 3 files
Prompt for AI agents (all 1 issues)
Understand the root cause of the following 1 issues and fix them.
<file name="core/util/repoUrl.ts">
<violation number="1" location="core/util/repoUrl.ts:52">
Checking `normalized.includes("://")` treats any query/fragment containing `://` as a fully qualified URL, so shorthand repo strings like `owner/repo?redirect=https://example.com` are no longer normalized to the canonical GitHub URL. Please detect schemes only when they appear at the start of the string.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed changes from recent commits (found 1 issue).
1 issue found across 2 files
Prompt for AI agents (all 1 issues)
Understand the root cause of the following 1 issues and fix them.
<file name="core/util/sanitization.vitest.ts">
<violation number="1" location="core/util/sanitization.vitest.ts:185">
Hard-coding /bin/sh for execSync causes these tests to fail on Windows where that shell path is absent. Please use a cross-platform shell selection so the suite runs on Windows too.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
|
✅ Review Complete Triggered by @tomasz-stefaniak's request Code Review for PR #8270: Build a local takeover MVPSummaryThis PR implements a "Background Mode" feature allowing users to create long-running background agents from chat, view recent tasks, and take over an agent locally. The implementation includes proper security measures for shell command injection and input validation. Overall quality is good with comprehensive test coverage. Critical IssuesNone identified - The code properly addresses the primary security concerns around command injection through sanitization utilities. Security Observations✅ Well handled:
Bugs / Potential Issues
Code Quality Issues
Missing TestsThe security tests are excellent, but functional tests are missing:
Documentation Gaps
Positive Observations✅ Excellent security testing - The integration tests in ✅ Good error messages - User-facing errors are clear and actionable ✅ Comprehensive URL normalization tests - Edge cases well covered ✅ Type safety - Proper TypeScript types throughout Minor Suggestions
ConclusionThis is solid work with good security practices. The main areas for improvement are:
The security implementation with sanitization + validation is exemplary. Nice job! 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed changes from recent commits (found 1 issue).
1 issue found across 3 files
Prompt for AI agents (all 1 issues)
Understand the root cause of the following 1 issues and fix them.
<file name="core/util/repoUrl.ts">
<violation number="1" location="core/util/repoUrl.ts:52">
The new scheme detection rejects git+ssh:// and other valid protocols containing +, -, or . and wrongly treats them as shorthand owner/repo paths, producing malformed URLs. Please restore support for these schemes by allowing RFC 3986-compliant characters in the protocol portion.</violation>
</file>
React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| // Convert shorthand owner/repo to full URL | ||
| if ( | ||
| normalized.includes("/") && | ||
| !/^[a-z]+:\/\//i.test(normalized) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new scheme detection rejects git+ssh:// and other valid protocols containing +, -, or . and wrongly treats them as shorthand owner/repo paths, producing malformed URLs. Please restore support for these schemes by allowing RFC 3986-compliant characters in the protocol portion.
Prompt for AI agents
Address the following comment on core/util/repoUrl.ts at line 52:
<comment>The new scheme detection rejects git+ssh:// and other valid protocols containing +, -, or . and wrongly treats them as shorthand owner/repo paths, producing malformed URLs. Please restore support for these schemes by allowing RFC 3986-compliant characters in the protocol portion.</comment>
<file context>
@@ -49,7 +49,7 @@ export function normalizeRepoUrl(url: string): string {
if (
normalized.includes("/") &&
- !normalized.includes("://") &&
+ !/^[a-z]+:\/\//i.test(normalized) &&
!normalized.startsWith("git@")
) {
</file context>
| !/^[a-z]+:\/\//i.test(normalized) && | |
| !/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No issues found across 1 file
core/control-plane/client.ts
Outdated
| * @param agentSessionId - The ID of the agent session | ||
| * @returns The agent session view including metadata and status | ||
| */ | ||
| public async getAgentSession(agentSessionId: string): Promise<any | null> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit add a return type
| title={ | ||
| canOpenLocally | ||
| ? "Open this agent workflow locally" | ||
| : "This agent is for a different repository. Open the correct workspace to take over this workflow." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we able to display the name of the workspace here? If it can't be done easily, don't worry about it
tingwai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally too, looks great. Thanks for all the great work!
|
🎉 This PR is included in version 1.27.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.5.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.30.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.4.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Description
Build a takeover MVP
AI Code Review
@continue-reviewChecklist
Screen recording or screenshot
[ When applicable, please include a short screen recording or screenshot - this makes it much easier for us as contributors to review and understand your changes. See this PR as a good example. ]
Tests
[ What tests were added or updated to ensure the changes work as expected? ]
Summary by cubic
Add Background mode that lets users create long‑running background agents from chat, see recent tasks, and take over an agent locally by switching to its branch and loading its session. Also updates org-scoped hub links and adds IDE/webview protocol support.
New Features
Migration