Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
116 changes: 116 additions & 0 deletions cli/src/commands/colorblind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* /colorblind command - Toggle colorblind mode
*/
import type { Command } from "./core/types.js"
import { generateMessage } from "../ui/utils/messages.js"

export const colorblindCommand: Command = {
name: "colorblind",
aliases: ["cb"],
description: "Toggle colorblind-friendly theme",
usage: "/colorblind [on|off]",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would it not be enough to have the colorblind theme selectable via /theme?

The toggle mechanism hard resets to the dark them when the colorblind theme is un-toggled .

examples: ["/colorblind on", "/colorblind off", "/colorblind"],
category: "settings",
priority: 7,
arguments: [
{
name: "state",
description: "Enable or disable colorblind mode (optional for toggle)",
required: false,
placeholder: "on/off/toggle",
provider: async () => [
{
value: "on",
title: "Enable",
description: "Enable colorblind-friendly theme",
matchScore: 1.0,
highlightedValue: "on",
},
{
value: "off",
title: "Disable",
description: "Disable colorblind-friendly theme",
matchScore: 1.0,
highlightedValue: "off",
},
{
value: "toggle",
title: "Toggle",
description: "Toggle colorblind mode",
matchScore: 1.0,
highlightedValue: "toggle",
},
],
validate: async (value, _context) => {
const validValues = ["on", "off", "toggle"]
const isValid = validValues.includes(value.toLowerCase())

return {
valid: isValid,
...(isValid ? {} : { error: `Invalid state. Use: ${validValues.join(", ")}` }),
}
},
},
],
handler: async (context) => {
const { args, addMessage, setTheme, config, refreshTerminal } = context
const currentTheme = config.theme || "dark"

try {
let newState: "on" | "off"
let action: string

if (args.length === 0 || !args[0]) {
// Toggle mode
newState = currentTheme === "colorblind" ? "off" : "on"
action = "Toggled"
} else {
const stateArg = args[0].toLowerCase()
if (stateArg === "toggle") {
newState = currentTheme === "colorblind" ? "off" : "on"
action = "Toggled"
} else if (stateArg === "on") {
newState = "on"
action = "Enabled"
} else if (stateArg === "off") {
newState = "off"
action = "Disabled"
} else {
addMessage({
...generateMessage(),
type: "error",
content: `Invalid state "${stateArg}". Use: on, off, or toggle`,
})
return
}
}

if (newState === "on") {
// Enable colorblind mode
await setTheme("colorblind")
addMessage({
...generateMessage(),
type: "system",
content: `${action} colorblind-friendly theme.`,
})
} else {
// Disable colorblind mode - restore previous theme or use default
const previousTheme = currentTheme === "colorblind" ? "dark" : currentTheme
await setTheme(previousTheme)
addMessage({
...generateMessage(),
type: "system",
content: `${action} colorblind-friendly theme.`,
})
}

await refreshTerminal()
} catch (error) {
addMessage({
...generateMessage(),
type: "error",
content: `Failed to ${args[0] || "toggle"} colorblind mode: ${error instanceof Error ? error.message : String(error)}`,
})
}
},
}
2 changes: 2 additions & 0 deletions cli/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { themeCommand } from "./theme.js"
import { checkpointCommand } from "./checkpoint.js"
import { sessionCommand } from "./session.js"
import { condenseCommand } from "./condense.js"
import { colorblindCommand } from "./colorblind.js"

/**
* Initialize all commands
Expand All @@ -43,4 +44,5 @@ export function initializeCommands(): void {
commandRegistry.register(checkpointCommand)
commandRegistry.register(sessionCommand)
commandRegistry.register(condenseCommand)
commandRegistry.register(colorblindCommand)
}
93 changes: 93 additions & 0 deletions cli/src/constants/themes/colorblind.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* Colorblind-friendly theme for Kilo Code CLI
*
* Designed for users with various forms of color vision deficiency.
* Uses high contrast colors and patterns to ensure accessibility.
*/
import type { Theme } from "../../types/theme.js"

export const colorblindTheme: Theme = {
id: "colorblind",
name: "Colorblind Friendly",
type: "dark",

brand: {
primary: "#0072e3", // High contrast blue
secondary: "#00b3ff", // Bright cyan for contrast
},

semantic: {
success: "#00b3ff", // Bright cyan instead of green
error: "#ff4d4d", // Bright red
warning: "#ffcc00", // Bright yellow
info: "#0072e3", // Blue
neutral: "#ffffff", // White for maximum contrast
},

interactive: {
prompt: "#0072e3",
selection: "#333333",
hover: "#404040",
disabled: "#808080",
focus: "#00b3ff",
},

messages: {
user: "#0072e3",
assistant: "#00b3ff",
system: "#ffffff",
error: "#ff4d4d",
},

actions: {
approve: "#00b3ff", // Cyan instead of green
reject: "#ff4d4d", // Red
cancel: "#808080", // Gray
pending: "#ffcc00", // Yellow
},

code: {
addition: "#00b3ff", // Cyan for additions
deletion: "#ff4d4d", // Red for deletions
modification: "#ffcc00", // Yellow for modifications
context: "#808080",
lineNumber: "#808080",
},

markdown: {
text: "#ffffff",
heading: "#0072e3",
strong: "#ffffff",
em: "#cccccc",
code: "#00b3ff",
blockquote: "#808080",
link: "#0072e3",
list: "#ffffff",
},

ui: {
border: {
default: "#404040",
active: "#00b3ff",
warning: "#ffcc00",
error: "#ff4d4d",
},
text: {
primary: "#ffffff",
secondary: "#cccccc",
dimmed: "#808080",
highlight: "#0072e3",
},
background: {
default: "default",
elevated: "default",
},
},

status: {
online: "#00b3ff", // Cyan
offline: "#ff4d4d", // Red
busy: "#ffcc00", // Yellow
idle: "#808080", // Gray
},
}
3 changes: 3 additions & 0 deletions cli/src/constants/themes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { shadesOfPurpleTheme } from "./shades-of-purple.js"
import { ayuLightTheme } from "./ayu-light.js"
import { ansiTheme } from "./ansi.js"
import { ansiLightTheme } from "./ansi-light.js"
import { colorblindTheme } from "./colorblind.js"

/**
* Registry of all available themes
Expand All @@ -42,6 +43,7 @@ const themeRegistry: Record<ThemeId, Theme> = {
"ayu-light": ayuLightTheme,
ansi: ansiTheme,
"ansi-light": ansiLightTheme,
colorblind: colorblindTheme,
}

/**
Expand Down Expand Up @@ -125,3 +127,4 @@ export { shadesOfPurpleTheme } from "./shades-of-purple.js"
export { ayuLightTheme } from "./ayu-light.js"
export { ansiTheme } from "./ansi.js"
export { ansiLightTheme } from "./ansi-light.js"
export { colorblindTheme } from "./colorblind.js"