Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
43b524f
fix(webview): preserve existing text when selecting slash command at …
rakshith1928 Jun 26, 2026
e5c1bdd
remove unwanted check not related to pr
rakshith1928 Jun 26, 2026
66f42c1
fix(webview): update test mocks for new select() cursor usage and add…
rakshith1928 Jul 7, 2026
74cb1ad
chore: add changeset for slash command trailing text fix
rakshith1928 Jul 7, 2026
9cc9f73
fix(webview): add slashEnd signal to fix cursor-corruption bug when s…
rakshith1928 Jul 7, 2026
de3db79
chore(test): fix redundant double type assertion in use-slash-command…
rakshith1928 Jul 7, 2026
669fcc2
chore(test): fix memory test state and add memory command trailing te…
rakshith1928 Jul 28, 2026
828f038
Merge branch 'main' into fix/slash-command-preserve-inputs
rakshith1928 Jul 29, 2026
64f16b2
address the pr review comments
rakshith1928 Aug 13, 2026
5906cbb
Merge remote-tracking branch 'upstream/main' into fix/slash-command-p…
rakshith1928 Aug 13, 2026
bf2810a
fix(test): use full text length as onInput cursor in review slash test
rakshith1928 Aug 13, 2026
b5d436f
Merge branch 'fix/slash-command-preserve-inputs' of https://github.co…
rakshith1928 Aug 13, 2026
a9ff187
fix: preserve trailing text on no-argument /memory commands
rakshith1928 Aug 14, 2026
b578ca0
refactor: drop review commit and review pr slash suggestions
rakshith1928 Aug 14, 2026
b1aa2bc
fix(webview): place caret at start when preserving trailing text for …
rakshith1928 Aug 14, 2026
c1b7438
fix(kilo-memory): preserve trailing text for /memory show like other …
rakshith1928 Aug 14, 2026
c26bb84
fix(kilo-vscode): update mirrored /memory show fixture for rest field
rakshith1928 Aug 14, 2026
4664540
fix(kilo-vscode): format prompt-input-utils.ts to satisfy prettier
rakshith1928 Aug 14, 2026
366a1c9
fix(kilo-vscode): place caret at start for preserved /memory text
rakshith1928 Aug 14, 2026
d1cc665
Merge branch 'main' into fix/slash-command-preserve-inputs
rakshith1928 Aug 14, 2026
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
5 changes: 5 additions & 0 deletions .changeset/memory-show-preserve-text.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

Typing extra text after the `/memory show` command (for example `/memory show my notes`) used to clear that text from the chat input when the command ran. The text now stays in the input so you don't lose what you typed.
5 changes: 5 additions & 0 deletions .changeset/slash-command-preserve-text.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

Preserve existing text when selecting a slash command at the start of the chat input. Previously, typing `/new` or another slash command with text before the cursor would wipe the existing content entirely.
10 changes: 6 additions & 4 deletions packages/kilo-memory/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Help = {

type Show = {
kind: "show"
rest?: string
}

type Operation =
Expand All @@ -64,6 +65,7 @@ type Operation =
| {
kind: "operation"
operation: Exclude<MemoryOperation, "remember" | "correct" | "forget" | "purge" | "auto">
rest?: string
}

type Usage = {
Expand Down Expand Up @@ -93,10 +95,10 @@ function usage(reason: string): ParsedMemoryCommand {
}

function operation(verb: string, text: string): ParsedMemoryCommand | undefined {
if (verb === "on" || verb === "enable") return { kind: "operation", operation: "enable" }
if (verb === "off" || verb === "disable") return { kind: "operation", operation: "disable" }
if (verb === "on" || verb === "enable") return { kind: "operation", operation: "enable", rest: text }
if (verb === "off" || verb === "disable") return { kind: "operation", operation: "disable", rest: text }
if (verb === "status" || verb === "inspect" || verb === "rebuild") {
return { kind: "operation", operation: verb }
return { kind: "operation", operation: verb, rest: text }
}
if (verb === "purge") {
if (text.toLowerCase() === "confirm") return { kind: "operation", operation: "purge", confirm: true }
Expand Down Expand Up @@ -138,7 +140,7 @@ export function parseMemoryCommand(input: string): ParsedMemoryCommand | undefin
const parts = split(picked.rest)
const verb = parts.head
if (!verb) return { kind: "help" }
if (verb === "show") return { kind: "show" }
if (verb === "show") return { kind: "show", rest: parts.tail }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: The mirrored fixture test in the VS Code package wasn't updated for the new rest field

Show now always carries rest ("" even with no trailing text), so parseMemoryCommand("/memory show") returns { kind: "show", rest: "" }. The kilo-memory suite's expected() was updated accordingly, but packages/kilo-vscode/tests/unit/memory-command.test.ts (line 35) still returns { kind: "show" } while consuming this same shared command-cases.json — so the existing show fixtures (/mem show, /memory project show) and the new show preserves trailing text fixture all fail toEqual there. Suggest mirroring the change: if (item.result === "show") return { kind: "show", rest: item.rest ?? "" }.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed both follow-ups. I made the action-command caret position explicit when preserving trailing text, and updated the shared VS Code memory-command fixture expectations for the new show.rest field. Also added coverage for /memory show preserving trailing text.


const op = operation(verb, parts.tail)
if (op) return op
Expand Down
27 changes: 27 additions & 0 deletions packages/kilo-memory/test/command-cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"input": "/memory project show",
"result": "show"
},
{
"name": "show preserves trailing text",
"input": "/memory show draft notes",
"result": "show",
"rest": "draft notes"
},
{
"name": "status operation",
"input": "/memory status",
Expand Down Expand Up @@ -61,6 +67,27 @@
"result": "operation",
"operation": "rebuild"
},
{
"name": "rebuild keeps trailing text",
"input": "/memory rebuild hello",
"result": "operation",
"operation": "rebuild",
"rest": "hello"
},
{
"name": "enable keeps trailing text",
"input": "/memory on hello",
"result": "operation",
"operation": "enable",
"rest": "hello"
},
{
"name": "project scope rebuild keeps trailing text",
"input": "/memory project rebuild hello",
"result": "operation",
"operation": "rebuild",
"rest": "hello"
},
{
"name": "purge requires confirmation",
"input": "/memory purge",
Expand Down
5 changes: 3 additions & 2 deletions packages/kilo-memory/test/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ type Case = {
text?: string
query?: string
reason?: string
rest?: string
}

const cases = (await Bun.file(new URL("./command-cases.json", import.meta.url)).json()) as Case[]

function expected(item: Case): ParsedMemoryCommand | undefined {
if (item.result === "none") return
if (item.result === "help") return { kind: "help" }
if (item.result === "show") return { kind: "show" }
if (item.result === "show") return { kind: "show", rest: item.rest ?? "" }
if (item.result === "usage") return { kind: "usage", reason: item.reason ?? "" }
if (!item.operation) throw new Error(`Missing operation for fixture: ${item.name}`)
if (item.operation === "remember" || item.operation === "correct") {
Expand All @@ -37,7 +38,7 @@ function expected(item: Case): ParsedMemoryCommand | undefined {
if (item.confirm !== true) throw new Error(`Missing confirmation for fixture: ${item.name}`)
return { kind: "operation", operation: item.operation, confirm: true }
}
return { kind: "operation", operation: item.operation }
return { kind: "operation", operation: item.operation, rest: item.rest ?? "" }
}

describe("memory commands", () => {
Expand Down
5 changes: 3 additions & 2 deletions packages/kilo-vscode/tests/unit/memory-command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Case = {
text?: string
query?: string
reason?: string
rest?: string
}

const cases = (await Bun.file(
Expand All @@ -31,7 +32,7 @@ const cases = (await Bun.file(
function expected(item: Case): ParsedMemoryCommand | undefined {
if (item.result === "none") return
if (item.result === "help") return { kind: "help" }
if (item.result === "show") return { kind: "show" }
if (item.result === "show") return { kind: "show", rest: item.rest ?? "" }
if (item.result === "usage") return { kind: "usage", reason: item.reason ?? "" }
if (!item.operation) throw new Error(`Missing operation for fixture: ${item.name}`)
if (item.operation === "remember" || item.operation === "correct") {
Expand All @@ -50,7 +51,7 @@ function expected(item: Case): ParsedMemoryCommand | undefined {
if (item.confirm !== true) throw new Error(`Missing confirmation for fixture: ${item.name}`)
return { kind: "operation", operation: item.operation, confirm: true }
}
return { kind: "operation", operation: item.operation }
return { kind: "operation", operation: item.operation, rest: item.rest ?? "" }
}

describe("parseMemoryCommand", () => {
Expand Down
32 changes: 32 additions & 0 deletions packages/kilo-vscode/tests/unit/prompt-input-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
isPathMention,
applySandboxState,
applySandboxStates,
memoryRest,
} from "../../webview-ui/src/components/chat/prompt-input-utils"
import { parseMemoryCommand } from "../../webview-ui/src/utils/memory-command"

describe("applySandboxState", () => {
const state = (enabled: boolean, revision: number, sessionID = "ses_1", directory = "/repo") => ({
Expand Down Expand Up @@ -329,3 +331,33 @@ describe("isPathMention", () => {
expect(isPathMention("src/foo.ts")).toBe(true)
})
})

describe("memoryRest", () => {
it("keeps trailing text in the input after a no-argument memory command", () => {
// /memory rebuild hello -> rebuild executes, "hello" stays in the input.
// This is the submit-path half of the trailing-text bug: handleSend sets
// the input to memoryRest(parsed), so a regression would drop "hello".
const memory = parseMemoryCommand("/memory rebuild hello")
expect(memory).not.toBeUndefined()
expect(memoryRest(memory!)).toBe("hello")
})

it("keeps trailing text through the project scope", () => {
expect(memoryRest(parseMemoryCommand("/memory project rebuild hello")!)).toBe("hello")
})

it("returns empty string when a no-argument command has no trailing text", () => {
expect(memoryRest(parseMemoryCommand("/memory rebuild")!)).toBe("")
})

it("keeps trailing text in the input after the show command", () => {
// /memory show draft notes -> show executes, "draft notes" stays in the input.
expect(memoryRest(parseMemoryCommand("/memory show draft notes")!)).toBe("draft notes")
})

it("returns empty string for argument-taking operations", () => {
// remember/correct/forget/auto/purge consume their text, so nothing remains.
expect(memoryRest(parseMemoryCommand("/memory remember hello")!)).toBe("")
expect(memoryRest(parseMemoryCommand("/memory auto on")!)).toBe("")
})
})
Loading
Loading