Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/flat-jobs-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"kilo-code": major
"@kilocode/cli": patch
---

Add Local review mode
10 changes: 5 additions & 5 deletions cli/src/state/atoms/__tests__/keyboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1182,8 +1182,8 @@ describe("keypress atoms", () => {

it("should wrap around to first mode when at the last mode", async () => {
// Set initial mode to the last default mode
// DEFAULT_MODES order: architect, code, ask, debug, orchestrator
store.set(extensionModeAtom, "orchestrator")
// DEFAULT_MODES order: architect, code, ask, debug, orchestrator, review
store.set(extensionModeAtom, "review")
store.set(customModesAtom, [])

// Press Shift+Tab
Expand All @@ -1206,8 +1206,8 @@ describe("keypress atoms", () => {
})

it("should include custom modes in the cycle", async () => {
// Set initial mode to "orchestrator" (last default mode)
store.set(extensionModeAtom, "orchestrator")
// Set initial mode to "review" (last default mode)
store.set(extensionModeAtom, "review")
// Add a custom mode
store.set(customModesAtom, [
{
Expand All @@ -1233,7 +1233,7 @@ describe("keypress atoms", () => {
// Wait for async operations to complete
await new Promise((resolve) => setTimeout(resolve, 10))

// Should have cycled to the custom mode (after orchestrator)
// Should have cycled to the custom mode (after review)
const newMode = store.get(extensionModeAtom)
expect(newMode).toBe("custom-mode")
})
Expand Down
62 changes: 62 additions & 0 deletions packages/types/src/mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,66 @@ export const DEFAULT_MODES: readonly ModeConfig[] = [
customInstructions:
"Your role is to coordinate complex workflows by delegating tasks to specialized modes. As an orchestrator, you should:\n\n1. When given a complex task, break it down into logical subtasks that can be delegated to appropriate specialized modes.\n\n2. For each subtask, use the `new_task` tool to delegate. Choose the most appropriate mode for the subtask's specific goal and provide comprehensive instructions in the `message` parameter. These instructions must include:\n * All necessary context from the parent task or previous subtasks required to complete the work.\n * A clearly defined scope, specifying exactly what the subtask should accomplish.\n * An explicit statement that the subtask should *only* perform the work outlined in these instructions and not deviate.\n * An instruction for the subtask to signal completion by using the `attempt_completion` tool, providing a concise yet thorough summary of the outcome in the `result` parameter, keeping in mind that this summary will be the source of truth used to keep track of what was completed on this project.\n * A statement that these specific instructions supersede any conflicting general instructions the subtask's mode might have.\n\n3. Track and manage the progress of all subtasks. When a subtask is completed, analyze its results and determine the next steps.\n\n4. Help the user understand how the different subtasks fit together in the overall workflow. Provide clear reasoning about why you're delegating specific tasks to specific modes.\n\n5. When all subtasks are completed, synthesize the results and provide a comprehensive overview of what was accomplished.\n\n6. Ask clarifying questions when necessary to better understand how to break down complex tasks effectively.\n\n7. Suggest improvements to the workflow based on the results of completed subtasks.\n\nUse subtasks to maintain clarity. If a request significantly shifts focus or requires a different expertise (mode), consider creating a subtask rather than overloading the current one.",
},
// kilocode_change start - Review mode for local code reviews
{
slug: "review",
name: "Review",
iconName: "codicon-git-compare",
roleDefinition:
"You are Kilo Code, an expert code reviewer with deep expertise in software engineering best practices, security vulnerabilities, performance optimization, and code quality. Your role is advisory - provide clear, actionable feedback on code quality and potential issues.",
whenToUse:
"Use this mode when you need to review code changes. Ideal for reviewing uncommitted work before committing, comparing your branch against main/develop, or analyzing changes before merging.",
description: "Review code changes locally",
groups: ["read", "browser", "mcp", "command"],
customInstructions: `When you enter Review mode, you will receive a list of changed files. Use tools to explore the changes dynamically.

## How to Review

1. **Start with git diff**: Use \`execute_command\` to run \`git diff\` (for uncommitted) or \`git diff <base>..HEAD\` (for branch) to see the actual changes.

2. **Examine specific files**: For complex changes, use \`read_file\` to see the full file context, not just the diff.

3. **Gather history context**: Use \`git log\`, \`git blame\`, or \`git show\` when you need to understand why code was written a certain way.

4. **Be confident**: Only flag issues where you have high confidence. Use these thresholds:
- **CRITICAL (95%+)**: Security vulnerabilities, data loss risks, crashes, authentication bypasses
- **WARNING (85%+)**: Bugs, logic errors, performance issues, unhandled errors
- **SUGGESTION (75%+)**: Code quality improvements, best practices, maintainability
- **Below 75%**: Don't comment - gather more context first

5. **Focus on what matters**:
- Security: Injection, auth issues, data exposure
- Bugs: Logic errors, null handling, race conditions
- Performance: Inefficient algorithms, memory leaks
- Error handling: Missing try-catch, unhandled promises

6. **Don't flag**:
- Style preferences that don't affect functionality
- Minor naming suggestions
- Patterns that match existing codebase conventions

## Output Format

### Summary
2-3 sentences describing what this change does and your overall assessment.

### Issues Found
| Severity | File:Line | Issue |
|----------|-----------|-------|
| CRITICAL | path/file.ts:42 | Brief description |
| WARNING | path/file.ts:78 | Brief description |

If no issues: "No issues found."

### Detailed Findings
For each issue:
- **File:** \`path/to/file.ts:line\`
- **Confidence:** X%
- **Problem:** What's wrong and why it matters
- **Suggestion:** Recommended fix with code snippet

### Recommendation
One of: **APPROVE** | **APPROVE WITH SUGGESTIONS** | **NEEDS CHANGES** | **NEEDS DISCUSSION**`,
},
// kilocode_change end
] as const
26 changes: 24 additions & 2 deletions packages/types/src/vscode-extension-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ export interface ExtensionMessage {
| "customToolsResult"
| "modes"
| "taskWithAggregatedCosts"
| "skillsData" // kilocode_change: Skills data response
| "skillsData"
| "askReviewScope" // kilocode_change: Review mode scope selection
text?: string
// kilocode_change start
completionRequestId?: string // Correlation ID from request
Expand Down Expand Up @@ -442,6 +443,23 @@ export interface ExtensionMessage {
childrenCost: number
}
historyItem?: HistoryItem
// kilocode_change start: Review mode
reviewScopeInfo?: {
uncommitted: {
available: boolean
fileCount: number
filePreview?: string[]
}
branch: {
available: boolean
currentBranch: string
baseBranch: string
fileCount: number
filePreview?: string[]
}
error?: string
}
// kilocode_change end: Review mode
}

export type ExtensionState = Pick<
Expand Down Expand Up @@ -929,7 +947,8 @@ export interface WebviewMessage {
| "requestModes"
| "switchMode"
| "debugSetting"
| "refreshSkills" // kilocode_change: Request skills data refresh
| "refreshSkills"
| "reviewScopeSelected" // kilocode_change: Review mode scope selection
text?: string
suggestionLength?: number // kilocode_change: Length of accepted suggestion for telemetry
completionRequestId?: string // kilocode_change
Expand Down Expand Up @@ -1049,6 +1068,9 @@ export interface WebviewMessage {
codebaseIndexOpenRouterApiKey?: string
}
updatedSettings?: RooCodeSettings
// kilocode_change start: Review mode
reviewScope?: "uncommitted" | "branch"
// kilocode_change end: Review mode
}

// kilocode_change: Create discriminated union for type-safe messages
Expand Down
64 changes: 64 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,12 @@ export class ClineProvider
}

await this.postStateToWebview()

// kilocode_change start: Review mode scope selection
if (newMode === "review") {
await this.triggerReviewScopeSelection()
}
// kilocode_change end
}

// Provider Profile Management
Expand Down Expand Up @@ -3379,6 +3385,64 @@ export class ClineProvider
await this.setValues({ mode })
}

// kilocode_change start: Review mode
/**
* Triggers the review scope selection UI
* Called when user enters review mode
*/
public async triggerReviewScopeSelection(): Promise<void> {
try {
const cwd = getWorkspacePath()
if (!cwd) {
this.log("Cannot start review: no workspace folder open")
return
}

const { ReviewService } = await import("../../services/review")
const reviewService = new ReviewService({ cwd })
const scopeInfo = await reviewService.getScopeInfo()

await this.postMessageToWebview({
type: "askReviewScope",
reviewScopeInfo: scopeInfo,
})
} catch (error) {
this.log(
`Error triggering review scope selection: ${error instanceof Error ? error.message : String(error)}`,
)
}
}

/**
* Handles the user's review scope selection
* Gets lightweight summary and starts the review task
* The agent will dynamically explore changes using tools
*/
public async handleReviewScopeSelected(scope: "uncommitted" | "branch"): Promise<void> {
try {
const cwd = getWorkspacePath()
if (!cwd) {
this.log("Cannot start review: no workspace folder open")
vscode.window.showErrorMessage("Cannot start review: no workspace folder open")
return
}

const { ReviewService, buildReviewPrompt } = await import("../../services/review")
const reviewService = new ReviewService({ cwd })

// Get lightweight summary - agent will explore details with tools
const summary = await reviewService.getReviewSummary(scope)

// Build the review prompt and start the task
// Let the agent handle cases with no changes - it can explain and offer alternatives
const reviewPrompt = buildReviewPrompt(summary)
await this.createTask(reviewPrompt)
} catch (error) {
this.log(`Error handling review scope selection: ${error instanceof Error ? error.message : String(error)}`)
}
}
// kilocode_change end: Review mode

// Provider Profiles

public async getProviderProfiles(): Promise<{ name: string; provider?: string }[]> {
Expand Down
10 changes: 10 additions & 0 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4594,6 +4594,16 @@ export const webviewMessageHandler = async (
break
}

// kilocode_change start: Review mode scope selection
case "reviewScopeSelected": {
const scope = message.reviewScope
if (scope === "uncommitted" || scope === "branch") {
await provider.handleReviewScopeSelected(scope)
}
break
}
// kilocode_change end

default: {
// console.log(`Unhandled message type: ${message.type}`)
//
Expand Down
Loading
Loading