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: 3 additions & 3 deletions apps/vscode-nightly/esbuild.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ async function main() {
sourcesContent: false,
platform: "node",
define: {
"process.env.PKG_NAME": '"kilo-code-nightly"',
"process.env.PKG_NAME": '"axon-code-nightly"',
"process.env.PKG_VERSION": `"${overrideJson.version}"`,
"process.env.PKG_OUTPUT_CHANNEL": '"Kilo-Code-Nightly"',
"process.env.PKG_OUTPUT_CHANNEL": '"Axon-Code-Nightly"',
...(gitSha ? { "process.env.PKG_SHA": `"${gitSha}"` } : {}),
},
}
Expand Down Expand Up @@ -88,7 +88,7 @@ async function main() {
const generatedPackageJson = generatePackageJson({
packageJson,
overrideJson,
substitution: ["kilo-code", "kilo-code-nightly"],
substitution: ["axon-code", "axon-code-nightly"],
})

fs.writeFileSync(path.join(buildDir, "package.json"), JSON.stringify(generatedPackageJson, null, 2))
Expand Down
2 changes: 1 addition & 1 deletion packages/cloud/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ExtensionContext } from "vscode"

export function getUserAgent(context?: ExtensionContext): string {
return `Kilo-Code ${context?.extension?.packageJSON?.version || "unknown"}`
return `Axon-Code ${context?.extension?.packageJSON?.version || "unknown"}`
}
2 changes: 1 addition & 1 deletion src/api/providers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export const DEFAULT_HEADERS = {
"HTTP-Referer": getAppUrl(),
"X-Title": "Axon Code",
[X_KILOCODE_VERSION]: Package.version,
"User-Agent": `Kilo-Code/${Package.version}`,
"User-Agent": `Axon-Code/${Package.version}`,
}
69 changes: 35 additions & 34 deletions src/api/providers/kilocode-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,40 +96,41 @@ export const KILO_CODE_MODELS: Record<string, KiloCodeModel> = {
input_cache_writes: "0",
},
},
// "axon-code-exp": {
// id: "axon-code-exp",
// name: "Axon Code Exp",
// description: "Axon Code is super intelligent LLM model for coding tasks",
// input_modalities: ["text"],
// context_length: 256000,
// max_output_length: 32768,
// output_modalities: ["text"],
// supported_sampling_parameters: [
// "temperature",
// "top_p",
// "top_k",
// "repetition_penalty",
// "frequency_penalty",
// "presence_penalty",
// "seed",
// "stop",
// ],
// supported_features: ["tools", "structured_outputs", "web_search"],
// openrouter: {
// slug: "matterai/axon",
// },
// datacenters: [{ country_code: "US" }],
// created: 1750426201,
// owned_by: "matterai",
// pricing: {
// prompt: "0.000001",
// completion: "0.000004",
// image: "0",
// request: "0",
// input_cache_reads: "0",
// input_cache_writes: "0",
// },
// },
"axon-code-2-preview": {
id: "axon-code-2-preview",
name: "Axon Code 2 (Preview)",
description:
"Axon Code 2 is the next-generation of Axon Code for coding tasks, currently in experimental stage.",
input_modalities: ["text"],
context_length: 256000,
max_output_length: 32768,
output_modalities: ["text"],
supported_sampling_parameters: [
"temperature",
"top_p",
"top_k",
"repetition_penalty",
"frequency_penalty",
"presence_penalty",
"seed",
"stop",
],
supported_features: ["tools", "structured_outputs", "web_search"],
openrouter: {
slug: "matterai/axon",
},
datacenters: [{ country_code: "US" }],
created: 1750426201,
owned_by: "matterai",
pricing: {
prompt: "0.000001",
completion: "0.000004",
image: "0",
request: "0",
input_cache_reads: "0",
input_cache_writes: "0",
},
},
// "gemini-3-flash-preview": {
// id: "gemini-3-flash-preview",
// name: "Gemini 3 Flash Preview",
Expand Down
70 changes: 33 additions & 37 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -675,51 +675,44 @@ export const webviewMessageHandler = async (
const pendingEdits = currentTask.fileEditReviewController.getPendingEdits()

const files = Array.from(pendingEdits.values()).map((edit) => {
// Calculate additions and deletions from content differences
let additions = 0
let deletions = 0

const beforeLines = (edit.originalContent || "").split("\n")

// Read the current file content to get the "after" state
let afterLines: string[] = []
try {
// Use the absolute path to read the current file content
const currentContent = require("fs").readFileSync(edit.absolutePath, "utf-8")
afterLines = currentContent.split("\n")
} catch (error) {
// File might have been deleted or not yet created
afterLines = []
}

// Simple line-based diff calculation
if (beforeLines.length === 0 && afterLines.length > 0) {
// New file
additions = afterLines.length
} else if (beforeLines.length > 0 && afterLines.length === 0) {
// Deleted file
deletions = beforeLines.length
} else {
// Modified file - use simple line count difference
const lineDiff = afterLines.length - beforeLines.length
if (lineDiff > 0) {
additions = lineDiff
// Calculate additions and deletions from all accumulated edits
let totalAdditions = 0
let totalDeletions = 0

// Process each edit to accumulate diff stats
for (const editEntry of edit.edits) {
const beforeLines = (editEntry.originalContent || "").split("\n")
const afterLines = (editEntry.newContent || "").split("\n")

// Simple line-based diff calculation for each edit
if (beforeLines.length === 0 && afterLines.length > 0) {
// New content added
totalAdditions += afterLines.length
} else if (beforeLines.length > 0 && afterLines.length === 0) {
// Content deleted
totalDeletions += beforeLines.length
} else {
deletions = Math.abs(lineDiff)
}
// If same line count, assume at least some lines changed
if (lineDiff === 0 && beforeLines.some((line, i) => line !== afterLines[i])) {
additions = 1
deletions = 1
// Modified content - use simple line count difference
const lineDiff = afterLines.length - beforeLines.length
if (lineDiff > 0) {
totalAdditions += lineDiff
} else {
totalDeletions += Math.abs(lineDiff)
}
// If same line count, assume at least some lines changed
if (lineDiff === 0 && beforeLines.some((line, i) => line !== afterLines[i])) {
totalAdditions += 1
totalDeletions += 1
}
}
}
Comment on lines +683 to 708
Copy link
Contributor

Choose a reason for hiding this comment

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

🟠 Logic Error

Issue: The diff calculation logic has two flaws:

  1. split(' ') on an empty string returns [''] (length 1), causing new or empty files to be counted as modifications (+1/-1) instead of pure additions/deletions.
  2. For modified files with line count changes (lineDiff > 0), the current logic ignores content changes in the overlapping lines, leading to under-reported stats.

Fix: Handle empty content explicitly to return empty arrays, and use a heuristic that counts changes in the overlapping region in addition to the length difference.

Impact: Ensures accurate diff statistics in the review UI.

Suggested change
for (const editEntry of edit.edits) {
const beforeLines = (editEntry.originalContent || "").split("\n")
const afterLines = (editEntry.newContent || "").split("\n")
// Simple line-based diff calculation for each edit
if (beforeLines.length === 0 && afterLines.length > 0) {
// New content added
totalAdditions += afterLines.length
} else if (beforeLines.length > 0 && afterLines.length === 0) {
// Content deleted
totalDeletions += beforeLines.length
} else {
deletions = Math.abs(lineDiff)
}
// If same line count, assume at least some lines changed
if (lineDiff === 0 && beforeLines.some((line, i) => line !== afterLines[i])) {
additions = 1
deletions = 1
// Modified content - use simple line count difference
const lineDiff = afterLines.length - beforeLines.length
if (lineDiff > 0) {
totalAdditions += lineDiff
} else {
totalDeletions += Math.abs(lineDiff)
}
// If same line count, assume at least some lines changed
if (lineDiff === 0 && beforeLines.some((line, i) => line !== afterLines[i])) {
totalAdditions += 1
totalDeletions += 1
}
}
}
for (const editEntry of edit.edits) {
const beforeLines = editEntry.originalContent ? editEntry.originalContent.split("\n") : []
const afterLines = editEntry.newContent ? editEntry.newContent.split("\n") : []
// Calculate additions/deletions based on length difference
const lineDiff = afterLines.length - beforeLines.length
if (lineDiff > 0) {
totalAdditions += lineDiff
} else {
totalDeletions += Math.abs(lineDiff)
}
// Check for modified lines in the overlapping region
const commonLength = Math.min(beforeLines.length, afterLines.length)
for (let i = 0; i < commonLength; i++) {
if (beforeLines[i] !== afterLines[i]) {
totalAdditions++
totalDeletions++
}
}
}


return {
relPath: edit.relPath,
absolutePath: edit.absolutePath,
stat: {
additions,
deletions,
additions: totalAdditions,
deletions: totalDeletions,
},
}
})
Expand Down Expand Up @@ -1082,6 +1075,9 @@ export const webviewMessageHandler = async (
case "fileEditReviewAcceptAll":
await vscode.commands.executeCommand("axon-code.fileEdit.acceptAll")
break
case "fileEditReviewRejectAll":
await vscode.commands.executeCommand("axon-code.fileEdit.rejectAll")
break
case "tasksByIdRequest": {
const request = message.payload as TasksByIdRequestPayload
await provider.postMessageToWebview({
Expand Down
2 changes: 1 addition & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ let userInfoHandler: ((data: { userInfo: CloudUserInfo }) => Promise<void>) | un
// Your extension is activated the very first time the command is executed.
export async function activate(context: vscode.ExtensionContext) {
extensionContext = context
outputChannel = vscode.window.createOutputChannel("Kilo-Code")
outputChannel = vscode.window.createOutputChannel("Axon-Code")
context.subscriptions.push(outputChannel)
outputChannel.appendLine(`${Package.name} extension activated - ${JSON.stringify(Package)}`)

Expand Down
76 changes: 61 additions & 15 deletions src/integrations/editor/FileEditReviewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ type PendingFileEdit = {
absolutePath: string
originalContent: string
diffAnchor: vscode.Range
edits: Array<{
originalContent: string
newContent: string
diffAnchor: vscode.Range
}>
}

const highlightDecorationType = vscode.window.createTextEditorDecorationType({
Expand All @@ -20,6 +25,7 @@ const highlightDecorationType = vscode.window.createTextEditorDecorationType({
const ACCEPT_COMMAND = "axon-code.fileEdit.accept"
const ACCEPT_ALL_COMMAND = "axon-code.fileEdit.acceptAll"
const REJECT_COMMAND = "axon-code.fileEdit.reject"
const REJECT_ALL_COMMAND = "axon-code.fileEdit.rejectAll"
const NEXT_COMMAND = "axon-code.fileEdit.reviewNext"

export class FileEditReviewController implements vscode.Disposable {
Expand Down Expand Up @@ -52,6 +58,7 @@ export class FileEditReviewController implements vscode.Disposable {
vscode.commands.registerCommand(ACCEPT_COMMAND, (arg?: any) => this.handleAccept(arg)),
vscode.commands.registerCommand(ACCEPT_ALL_COMMAND, () => this.handleAcceptAll()),
vscode.commands.registerCommand(REJECT_COMMAND, (arg?: any) => this.handleReject(arg)),
vscode.commands.registerCommand(REJECT_ALL_COMMAND, () => this.handleRejectAll()),
vscode.commands.registerCommand(NEXT_COMMAND, () => this.handleReviewNext()),
)
}
Expand Down Expand Up @@ -83,18 +90,35 @@ export class FileEditReviewController implements vscode.Disposable {
// },
// ]

const pending: PendingFileEdit = {
relPath: params.relPath,
readablePath,
absolutePath: params.absolutePath,
const edit = {
originalContent: params.originalContent,
newContent: params.newContent,
diffAnchor,
}

this.pendingEdits.set(readablePath, pending)
// Ensure unique queue items
this.reviewQueue = this.reviewQueue.filter((path) => path !== readablePath)
this.reviewQueue.push(readablePath)
const existingEntry = this.pendingEdits.get(readablePath)
if (existingEntry) {
// Add to existing edits array
existingEntry.edits.push(edit)
// Update the main diff anchor to the first edit for consistency
if (existingEntry.edits.length === 1) {
existingEntry.diffAnchor = edit.diffAnchor
}
} else {
// Create new entry
const pending: PendingFileEdit = {
relPath: params.relPath,
readablePath,
absolutePath: params.absolutePath,
originalContent: params.originalContent,
diffAnchor,
edits: [edit],
}
this.pendingEdits.set(readablePath, pending)
// Ensure unique queue items
this.reviewQueue = this.reviewQueue.filter((path) => path !== readablePath)
this.reviewQueue.push(readablePath)
}

this.refreshDecorations()
this.codeLensEmitter.fire()
Expand Down Expand Up @@ -132,7 +156,7 @@ export class FileEditReviewController implements vscode.Disposable {
return
}

// Accept means we keep the changes. Just clean up.
// Accept means we keep the changes. Just clean up all edits for this file.
this.clearEntry(entry)
this.refreshDecorations()

Expand Down Expand Up @@ -169,6 +193,7 @@ export class FileEditReviewController implements vscode.Disposable {
return
}

// Reject means we restore the original content (first edit's original content)
await fs.writeFile(entry.absolutePath, entry.originalContent, "utf-8")
// Force reload/save not strictly needed as file watcher handles it,
// but ensures editor updates
Expand All @@ -190,6 +215,20 @@ export class FileEditReviewController implements vscode.Disposable {
this.codeLensEmitter.fire()
}

async handleRejectAll() {
if (this.pendingEdits.size === 0) return

// Reject all edits by restoring original content for each file
for (const entry of this.pendingEdits.values()) {
await fs.writeFile(entry.absolutePath, entry.originalContent, "utf-8")
}

this.pendingEdits.clear()
this.reviewQueue = []
this.refreshDecorations()
this.codeLensEmitter.fire()
}

async handleReviewNext() {
const nextEntry = this.getNextEntry()
if (!nextEntry) {
Expand Down Expand Up @@ -239,10 +278,13 @@ export class FileEditReviewController implements vscode.Disposable {

const highlightDecorations: vscode.DecorationOptions[] = []

if (entry) {
highlightDecorations.push({
range: entry.diffAnchor,
})
if (entry && entry.edits.length > 0) {
// Show decorations for all edits in this file
for (const edit of entry.edits) {
highlightDecorations.push({
range: edit.diffAnchor,
})
}
}

editor.setDecorations(highlightDecorationType, highlightDecorations)
Expand Down Expand Up @@ -294,14 +336,18 @@ class FileEditReviewCodeLensProvider implements vscode.CodeLensProvider {
provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] {
const readablePath = getReadablePath(this.cwd, path.relative(this.cwd, document.uri.fsPath))
const entry = this.getPendingEdits().get(readablePath)
if (!entry) return []
if (!entry || entry.edits.length === 0) return []

const line = Math.max(0, entry.diffAnchor.start.line)
const anchor = new vscode.Range(line, 0, line, 0)

// Show edit count in the title if there are multiple edits
const editCount = entry.edits.length
const titleSuffix = editCount > 1 ? ` (${editCount} edits)` : ""

return [
new vscode.CodeLens(anchor, {
title: "Accept",
title: `Accept${titleSuffix}`,
command: ACCEPT_COMMAND,
arguments: [entry.relPath],
}),
Expand Down
2 changes: 1 addition & 1 deletion src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"displayName": "%extension.displayName%",
"description": "%extension.description%",
"publisher": "matterai",
"version": "4.202.0",
"version": "4.204.0",
"icon": "assets/icons/matterai-ic.png",
"galleryBanner": {
"color": "#FFFFFF",
Expand Down
Loading
Loading