diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dfff1d7d146..9dce2b91bdf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,3 @@
-
# Contributing to the Project
We welcome contributions in the form of bug reports, feature requests,
@@ -24,30 +23,29 @@ ensure that your contributions can be integrated smoothly.
```bash
# Clone the repository
-git clone https://github.com/dwash96/aider-ce.git
-cd aider-ce
+git clone https://github.com/dwash96/cecli.git
+cd cecli
# Make a venv
python3 -m venv venv
source venv/bin/activate
-# Install UV because it's superior
+# Install UV because it's superior (skip if you already have it installed globally)
pip install uv
# Build Project
uv pip install --native-tls -e .
# Add tool chain
-uv install --native-tls pre-commit
+uv pip install --native-tls pre-commit
pre-commit install
# Run Program
-aider-ce
-
-# OR!
-
cecli
+# OR! (legacy)
+aider-ce
+
```
### Building the Docker Image
diff --git a/README.md b/README.md
index 94d99f0d637..a16a4732e1b 100644
--- a/README.md
+++ b/README.md
@@ -16,15 +16,15 @@ LLMs are a part of our lives from here on out so join us in learning about and c
## Documentation/Other Notes:
-* [Agent Mode](https://github.com/dwash96/cecli/blob/main/aider/website/docs/config/agent-mode.md)
-* [MCP Configuration](https://github.com/dwash96/cecli/blob/main/aider/website/docs/config/mcp.md)
-* [TUI Configuration](https://github.com/dwash96/cecli/blob/main/aider/website/docs/config/tui.md)
-* [Skills](https://github.com/dwash96/cecli/blob/main/aider/website/docs/config/skills.md)
-* [Session Management](https://github.com/dwash96/cecli/blob/main/aider/website/docs/sessions.md)
+* [Agent Mode](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/agent-mode.md)
+* [MCP Configuration](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/mcp.md)
+* [TUI Configuration](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/tui.md)
+* [Skills](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/skills.md)
+* [Session Management](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/sessions.md)
* [Custom Commands](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/custom-commands.md)
* [Custom System Prompts](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/custom-system-prompts.md)
* [Custom Tools](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/agent-mode.md#creating-custom-tools)
-* [Advanced Model Configuration](https://github.com/dwash96/cecli/blob/main/aider/website/docs/config/model-aliases.md#advanced-model-settings)
+* [Advanced Model Configuration](https://github.com/dwash96/cecli/blob/main/cecli/website/docs/config/model-aliases.md#advanced-model-settings)
* [Aider Original Documentation (still mostly applies)](https://aider.chat/)
You can see a selection of the enhancements and updates by comparing the help output:
@@ -101,7 +101,15 @@ DEEPSEEK_API_KEY="..."
### Run Program
-If you are in the directory with your .aider.conf.yml file, then simply running `cecli` or `aider-ce` will start the agent with your configuration. If you want additional sandboxing, we publish a docker container that can be ran as follows:
+If you are in the directory with your .aider.conf.yml file, then simply running `cecli` or `aider-ce` will start the agent with your configuration. For best results, since terminal emulators can be finicky, we highly suggest running:
+
+```bash
+cecli --terminal-setup
+```
+
+On first run to configure keybindings for the program (notably `shift+enter`). Support for terminals is ongoing so feel free to make a github issue or chat in the discord for us to figure out what's needed to support automatically setting up a given terminal.
+
+If you want additional sandboxing, we publish a docker container that can be ran as follows:
```bash
docker pull dustinwashington/aider-ce
@@ -464,4 +472,4 @@ The current priorities are to improve core capabilities and user experience of t
|
-
\ No newline at end of file
+
diff --git a/cecli/__init__.py b/cecli/__init__.py
index 8b88d2cdae1..b4224a3f34d 100644
--- a/cecli/__init__.py
+++ b/cecli/__init__.py
@@ -1,6 +1,6 @@
from packaging import version
-__version__ = "0.95.7.dev"
+__version__ = "0.95.8.dev"
safe_version = __version__
try:
diff --git a/cecli/args.py b/cecli/args.py
index ceac5c75256..1ba9de0cd7f 100644
--- a/cecli/args.py
+++ b/cecli/args.py
@@ -456,6 +456,17 @@ def get_parser(default_config_files, git_root):
default=False,
help="Restore the previous chat history messages (default: False)",
)
+ #########
+ group = parser.add_argument_group("Input settings")
+ group.add_argument(
+ "--terminal-setup",
+ action=argparse.BooleanOptionalAction,
+ default=False,
+ help=(
+ "Auto-configure terminal emulator for shift+enter support for new lines (default:"
+ " False)"
+ ),
+ )
##########
group = parser.add_argument_group("Output settings")
group.add_argument(
diff --git a/cecli/commands/__init__.py b/cecli/commands/__init__.py
index 6b118475204..b399b855792 100644
--- a/cecli/commands/__init__.py
+++ b/cecli/commands/__init__.py
@@ -51,6 +51,7 @@
from .save import SaveCommand
from .save_session import SaveSessionCommand
from .settings import SettingsCommand
+from .terminal_setup import TerminalSetupCommand
from .test import TestCommand
from .think_tokens import ThinkTokensCommand
from .tokens import TokensCommand
@@ -123,6 +124,7 @@
CommandRegistry.register(CommandPrefixCommand)
CommandRegistry.register(LoadSkillCommand)
CommandRegistry.register(RemoveSkillCommand)
+CommandRegistry.register(TerminalSetupCommand)
__all__ = [
@@ -187,6 +189,7 @@
"CommandPrefixCommand",
"LoadSkillCommand",
"RemoveSkillCommand",
+ "TerminalSetupCommand",
"SwitchCoderSignal",
"Commands",
]
diff --git a/cecli/commands/terminal_setup.py b/cecli/commands/terminal_setup.py
new file mode 100644
index 00000000000..3857ecd8d71
--- /dev/null
+++ b/cecli/commands/terminal_setup.py
@@ -0,0 +1,365 @@
+import json
+import os
+import platform
+import shutil
+from pathlib import Path
+from typing import List
+
+from cecli.commands.utils.base_command import BaseCommand
+from cecli.commands.utils.helpers import format_command_result
+
+
+class TerminalSetupCommand(BaseCommand):
+ NORM_NAME = "terminal-setup"
+ DESCRIPTION = "Configure terminal config files to support shift+enter for newline"
+
+ # Configuration constants
+ ALACRITTY_BINDING = """
+# Added by cecli terminal-setup command
+[[keyboard.bindings]]
+key = "Return"
+mods = "Shift"
+chars = "\\n"
+"""
+
+ KITTY_BINDING = "\n# Added by cecli terminal-setup command\nmap shift+enter send_text all \\n\n"
+
+ WT_ACTION = {
+ "command": {"action": "sendInput", "input": "\n"},
+ "id": "User.sendInput.shift_enter",
+ }
+
+ WT_KEYBINDING = {"id": "User.sendInput.shift_enter", "keys": "shift+enter"}
+
+ @classmethod
+ def _get_config_paths(cls):
+ """Determine paths based on the current OS."""
+ system = platform.system()
+ home = Path.home()
+ paths = {}
+
+ # Check for WSL specifically
+ is_wsl_env = "microsoft" in platform.uname().release.lower()
+
+ if system == "Linux":
+ # Standard Linux paths (applies to WSL instances of Kitty/Alacritty too)
+ paths["alacritty"] = home / ".config" / "alacritty" / "alacritty.toml"
+ paths["kitty"] = home / ".config" / "kitty" / "kitty.conf"
+
+ if is_wsl_env:
+ # Try to find Windows Terminal settings from inside WSL
+ # We have to guess the Windows username, usually defaults to the WSL user
+ # or requires searching /mnt/c/Users/
+ try:
+ # Get Windows username by invoking cmd.exe (slow but accurate)
+ win_user = os.popen("cmd.exe /c 'echo %USERNAME%'").read().strip()
+ if win_user:
+ win_home = Path(f"/mnt/c/Users/{win_user}")
+ local_appdata = win_home / "AppData/Local"
+ wt_glob = list(
+ local_appdata.glob(
+ "Packages/Microsoft.WindowsTerminal_*/LocalState/settings.json"
+ )
+ )
+ if wt_glob:
+ paths["windows_terminal"] = wt_glob[0]
+ except Exception:
+ pass # cmd.exe might not be in path or accessible
+
+ elif system == "Darwin": # macOS
+ paths["alacritty"] = home / ".config" / "alacritty" / "alacritty.toml"
+ paths["kitty"] = home / ".config" / "kitty" / "kitty.conf"
+
+ elif system == "Windows":
+ appdata = Path(os.getenv("APPDATA"))
+ paths["alacritty"] = appdata / "alacritty" / "alacritty.toml"
+ paths["kitty"] = appdata / "kitty" / "kitty.conf"
+
+ # Windows Terminal path is tricky (has a unique hash in folder name)
+ # We look for the folder starting with Microsoft.WindowsTerminal
+ local_appdata = Path(os.getenv("LOCALAPPDATA"))
+ wt_glob = list(
+ local_appdata.glob("Packages/Microsoft.WindowsTerminal_*/LocalState/settings.json")
+ )
+ if wt_glob:
+ paths["windows_terminal"] = wt_glob[0]
+
+ return paths
+
+ @classmethod
+ def _backup_file(cls, file_path, io):
+ """Creates a copy of the file with .bak extension."""
+ if file_path.exists():
+ backup_path = file_path.with_suffix(file_path.suffix + ".bak")
+ shutil.copy(file_path, backup_path)
+ io.tool_output(f"Backed up {file_path.name} to {backup_path.name}")
+ return True
+ return False
+
+ @classmethod
+ def _update_alacritty(cls, path, io, dry_run=False):
+ """Appends the TOML configuration if not already present."""
+ if not path.exists():
+ io.tool_output(f"Skipping Alacritty: File not found at {path}")
+ return False
+
+ if dry_run:
+ io.tool_output(f"DRY-RUN: Would check Alacritty config at {path}")
+ io.tool_output(f"DRY-RUN: Would append binding:\n{cls.ALACRITTY_BINDING.strip()}")
+ # Simulate checking for duplicates
+ try:
+ with open(path, "r", encoding="utf-8") as f:
+ content = f.read()
+ if (
+ 'key = "Return"' in content
+ and 'mods = "Shift"' in content
+ and 'chars = "\\n"' in content
+ ):
+ io.tool_output("DRY-RUN: Alacritty already configured.")
+ return False
+ else:
+ io.tool_output("DRY-RUN: Would update Alacritty config.")
+ return True
+ except Exception as e:
+ io.tool_output(f"DRY-RUN: Error reading file: {e}")
+ return False
+
+ cls._backup_file(path, io)
+
+ with open(path, "r", encoding="utf-8") as f:
+ content = f.read()
+
+ # Simple check to avoid duplicates
+ if (
+ 'key = "Return"' in content
+ and 'mods = "Shift"' in content
+ and 'chars = "\\n"' in content
+ ):
+ io.tool_output("Alacritty already configured.")
+ return False
+
+ with open(path, "a", encoding="utf-8") as f:
+ f.write(cls.ALACRITTY_BINDING)
+ io.tool_output("Updated Alacritty config.")
+ return True
+
+ @classmethod
+ def _update_kitty(cls, path, io, dry_run=False):
+ """Appends the Kitty mapping if not present."""
+ if not path.exists():
+ io.tool_output(f"Skipping Kitty: File not found at {path}")
+ return False
+
+ if dry_run:
+ io.tool_output(f"DRY-RUN: Would check Kitty config at {path}")
+ io.tool_output(f"DRY-RUN: Would append binding:\n{cls.KITTY_BINDING.strip()}")
+ # Simulate checking for duplicates
+ try:
+ with open(path, "r", encoding="utf-8") as f:
+ content = f.read()
+ if "map shift+enter send_text all \\n" in content:
+ io.tool_output("DRY-RUN: Kitty already configured.")
+ return False
+ else:
+ io.tool_output("DRY-RUN: Would update Kitty config.")
+ return True
+ except Exception as e:
+ io.tool_output(f"DRY-RUN: Error reading file: {e}")
+ return False
+
+ cls._backup_file(path, io)
+
+ with open(path, "r", encoding="utf-8") as f:
+ content = f.read()
+
+ if "map shift+enter send_text all \\n" in content:
+ io.tool_output("Kitty already configured.")
+ return False
+
+ with open(path, "a", encoding="utf-8") as f:
+ f.write(cls.KITTY_BINDING)
+ io.tool_output("Updated Kitty config.")
+ return True
+
+ @classmethod
+ def _update_windows_terminal(cls, path, io, dry_run=False):
+ """Parses JSON, adds action to 'actions' list and keybinding to 'keybindings' list."""
+ if not path or not path.exists():
+ io.tool_output("Skipping Windows Terminal: File not found.")
+ return False
+
+ if dry_run:
+ io.tool_output(f"DRY-RUN: Would check Windows Terminal config at {path}")
+ io.tool_output(f"DRY-RUN: Would add action: {json.dumps(cls.WT_ACTION, indent=2)}")
+ io.tool_output(
+ f"DRY-RUN: Would add keybinding: {json.dumps(cls.WT_KEYBINDING, indent=2)}"
+ )
+ # Simulate checking for duplicates
+ try:
+ with open(path, "r", encoding="utf-8") as f:
+ data = json.load(f)
+
+ # Check if already configured
+ already_configured = False
+
+ # Check actions array for our action ID
+ actions_list = data.get("actions", [])
+ if isinstance(actions_list, list):
+ for action in actions_list:
+ if isinstance(action, dict) and action.get("id") == cls.WT_ACTION["id"]:
+ already_configured = True
+ break
+
+ # Check keybindings array for shift+enter
+ keybindings_list = data.get("keybindings", [])
+ if isinstance(keybindings_list, list):
+ for binding in keybindings_list:
+ if isinstance(binding, dict) and binding.get("keys") == "shift+enter":
+ already_configured = True
+ break
+
+ if already_configured:
+ io.tool_output("DRY-RUN: Windows Terminal already configured.")
+ return False
+ else:
+ io.tool_output("DRY-RUN: Would update Windows Terminal config.")
+ return True
+ except json.JSONDecodeError:
+ io.tool_output(
+ "DRY-RUN: Error: Could not parse Windows Terminal settings.json. Is it valid"
+ " JSON?"
+ )
+ return False
+ except Exception as e:
+ io.tool_output(f"DRY-RUN: Error reading file: {e}")
+ return False
+
+ try:
+ with open(path, "r", encoding="utf-8") as f:
+ data = json.load(f)
+
+ # Check if already configured
+ already_configured = False
+
+ # Check actions array for our action ID
+ actions_list = data.get("actions", [])
+ if not isinstance(actions_list, list):
+ actions_list = []
+ data["actions"] = actions_list
+
+ for action in actions_list:
+ if isinstance(action, dict) and action.get("id") == cls.WT_ACTION["id"]:
+ already_configured = True
+ break
+
+ # Check keybindings array for shift+enter
+ keybindings_list = data.get("keybindings", [])
+ if not isinstance(keybindings_list, list):
+ keybindings_list = []
+ data["keybindings"] = keybindings_list
+
+ for binding in keybindings_list:
+ if isinstance(binding, dict) and binding.get("keys") == "shift+enter":
+ already_configured = True
+ break
+
+ if already_configured:
+ io.tool_output("Windows Terminal already configured.")
+ return False
+
+ # Add our action to actions array
+ actions_list.append(cls.WT_ACTION)
+ data["actions"] = actions_list
+
+ # Add our keybinding to keybindings array
+ keybindings_list.append(cls.WT_KEYBINDING)
+ data["keybindings"] = keybindings_list
+
+ cls._backup_file(path, io)
+
+ with open(path, "w", encoding="utf-8") as f:
+ json.dump(data, f, indent=4)
+ io.tool_output("Updated Windows Terminal config.")
+ return True
+
+ except json.JSONDecodeError:
+ io.tool_output(
+ "Error: Could not parse Windows Terminal settings.json. Is it valid JSON?"
+ )
+ return False
+
+ @classmethod
+ async def execute(cls, io, coder, args, **kwargs):
+ """Configure terminal config files to support shift+enter for newline."""
+ io.tool_output(f"Detecting OS: {platform.system()}")
+ paths = cls._get_config_paths()
+
+ # Check for dry-run mode
+ dry_run = args == "dry_run"
+ if dry_run:
+ io.tool_output("DRY-RUN MODE: Showing what would be changed without modifying files\n")
+
+ updated = False
+
+ if "alacritty" in paths:
+ if cls._update_alacritty(paths["alacritty"], io, dry_run=dry_run):
+ updated = True
+
+ if "kitty" in paths:
+ if cls._update_kitty(paths["kitty"], io, dry_run=dry_run):
+ updated = True
+
+ if "windows_terminal" in paths:
+ if cls._update_windows_terminal(paths["windows_terminal"], io, dry_run=dry_run):
+ updated = True
+
+ if dry_run:
+ if updated:
+ io.tool_output(
+ "\nDRY-RUN: Would make changes (restart terminals for changes to take effect)."
+ )
+ else:
+ io.tool_output(
+ "\nDRY-RUN: No changes would be made (configurations already present or files"
+ " not found)."
+ )
+ return format_command_result(
+ io, "terminal-setup", "Dry-run completed - showing what would be changed"
+ )
+ elif updated:
+ io.tool_output("\nDone! Please restart your terminals for changes to take effect.")
+ return format_command_result(
+ io, "terminal-setup", "Successfully configured terminal settings"
+ )
+ else:
+ io.tool_output(
+ "\nNo changes were made (configurations already present or files not found)."
+ )
+ return format_command_result(
+ io, "terminal-setup", "No changes needed - configurations already present"
+ )
+
+ @classmethod
+ def get_completions(cls, io, coder, args) -> List[str]:
+ """Get completion options for terminal-setup command."""
+ return []
+
+ @classmethod
+ def get_help(cls) -> str:
+ """Get help text for the terminal-setup command."""
+ help_text = super().get_help()
+ help_text += "\nUsage:\n"
+ help_text += " /terminal-setup # Configure terminal to support shift+enter for newline\n"
+ help_text += (
+ " /terminal-setup --dry-run # Show what would be changed without modifying files\n"
+ )
+ help_text += (
+ "\nNote: This command modifies terminal configuration files (Alacritty, Kitty, Windows"
+ " Terminal)\n"
+ )
+ help_text += (
+ "to add a key binding that sends a newline character when shift+enter is pressed.\n"
+ )
+ help_text += "Backup copies are created with .bak extension before any modifications.\n"
+ help_text += "Use --dry-run to preview changes before applying them.\n"
+ return help_text
diff --git a/cecli/io.py b/cecli/io.py
index 482eebccf95..b4e18245059 100644
--- a/cecli/io.py
+++ b/cecli/io.py
@@ -396,9 +396,9 @@ def __init__(
self.fzf_available = shutil.which("fzf")
if not self.fzf_available and self.verbose:
- self.tool_warning(
- "fzf not found, fuzzy finder features will be disabled. Install it for enhanced"
- " file/history search."
+ print(
+ "Warning: fzf not found, fuzzy finder features will be disabled. Install it for"
+ " enhanced file/history search."
)
self.code_theme = code_theme
@@ -421,7 +421,7 @@ def __init__(
try:
Path(self.input_history_file).parent.mkdir(parents=True, exist_ok=True)
except (PermissionError, OSError) as e:
- self.tool_warning(f"Could not create directory for input history: {e}")
+ print(f"Warning: Could not create directory for input history: {e}")
self.input_history_file = None
if chat_history_file is not None:
@@ -490,11 +490,11 @@ def __init__(
self.console = Console() # pretty console
except Exception as err:
self.console = Console(force_terminal=False, no_color=True)
- self.tool_error(f"Can't initialize prompt toolkit: {err}") # non-pretty
+ print(f"Error: Can't initialize prompt toolkit: {err}") # non-pretty
else:
self.console = Console(force_terminal=False, no_color=True) # non-pretty
if self.is_dumb_terminal:
- self.tool_output("Detected dumb terminal, disabling fancy input and pretty output.")
+ print("Detected dumb terminal, disabling fancy input and pretty output.")
self.file_watcher = file_watcher
self.root = root
diff --git a/cecli/main.py b/cecli/main.py
index 371af61fc81..624af74cb4a 100644
--- a/cecli/main.py
+++ b/cecli/main.py
@@ -628,7 +628,7 @@ def get_io(pretty):
output_queue = None
input_queue = None
pre_init_io = get_io(args.pretty)
- if args.tui or args.linear_output is None:
+ if args.tui or (args.tui is None and not args.linear_output):
try:
from cecli.tui import create_tui_io
@@ -765,7 +765,7 @@ def get_io(pretty):
return await graceful_exit(None, 1)
alias, model = parts
models.MODEL_ALIASES[alias.strip()] = model.strip()
- selected_model_name = await select_default_model(args, io)
+ selected_model_name = await select_default_model(args, pre_init_io)
if not selected_model_name:
return await graceful_exit(None, 1)
args.model = selected_model_name
@@ -1087,6 +1087,11 @@ def apply_model_overrides(model_name):
io.tool_output("Dry run enabled, skipping commit.")
else:
await coder.commands.do_run("commit", "")
+ if args.terminal_setup:
+ if args.dry_run:
+ await coder.commands.do_run("terminal-setup", "dry_run")
+ else:
+ await coder.commands.do_run("terminal-setup", "")
if args.lint or args.test or args.commit:
return await graceful_exit(coder)
if args.show_repo_map:
diff --git a/cecli/tui/app.py b/cecli/tui/app.py
index f656decd06f..567243ccc19 100644
--- a/cecli/tui/app.py
+++ b/cecli/tui/app.py
@@ -165,9 +165,6 @@ def _get_config(self):
if "key_bindings" not in config:
config["key_bindings"] = {}
- coder = self.worker.coder
- is_multiline = coder.args.multiline
-
# Ensure colors dict has all expected keys with default values
default_colors = {
"primary": "#00ff5f",
@@ -188,8 +185,8 @@ def _get_config(self):
}
default_key_bindings = {
- "newline": "enter" if is_multiline else "shift+enter",
- "submit": "shift+enter" if is_multiline else "enter",
+ "newline": "shift+enter",
+ "submit": "enter",
"stop": "escape",
"cycle_forward": "tab",
"cycle_backward": "shift+tab",
diff --git a/cecli/tui/io.py b/cecli/tui/io.py
index 6ae017eaeb6..71ca7ded7bc 100644
--- a/cecli/tui/io.py
+++ b/cecli/tui/io.py
@@ -22,13 +22,13 @@ def __init__(self, output_queue, input_queue, **kwargs):
# Lazy-initialized console for TUI rendering
self._tui_console = None
- # Initialize parent (fancy_input should already be False from caller)
- super().__init__(**kwargs)
-
# Store queues
self.output_queue = output_queue
self.input_queue = input_queue
+ # Initialize parent (fancy_input should already be False from caller)
+ super().__init__(**kwargs)
+
# Current task tracking
self.current_task_id = None
diff --git a/cecli/urls.py b/cecli/urls.py
index 9a5c7b59d8a..7dfb384fe8e 100644
--- a/cecli/urls.py
+++ b/cecli/urls.py
@@ -8,9 +8,9 @@
token_limits = "https://cecli.dev/docs/troubleshooting/token-limits.html"
llms = "https://cecli.dev/docs/llms.html"
large_repos = "https://cecli.dev/docs/faq.html#can-i-use-cecli-in-a-large-mono-repo"
-github_issues = "https://github.com/dwash96/aider-ce/issues/new"
+github_issues = "https://github.com/dwash96/cecli/issues/new"
git_index_version = "https://github.com/Aider-AI/aider/issues/211"
install_properly = "https://cecli.dev/docs/troubleshooting/imports.html"
-release_notes = "https://github.com/dwash96/aider-ce/releases/latest"
+release_notes = "https://github.com/dwash96/cecli/releases/latest"
edit_formats = "https://cecli.dev/docs/more/edit-formats.html"
models_and_keys = "https://cecli.dev/docs/troubleshooting/models-and-keys.html"
diff --git a/cecli/versioncheck.py b/cecli/versioncheck.py
index 0563cd618d6..407f8725748 100644
--- a/cecli/versioncheck.py
+++ b/cecli/versioncheck.py
@@ -60,7 +60,7 @@ async def check_version(io, just_check=False, verbose=False):
import requests
try:
- response = requests.get("https://pypi.org/pypi/aider-ce/json")
+ response = requests.get("https://pypi.org/pypi/cecli-dev/json")
data = response.json()
latest_version = data["info"]["version"]
current_version = cecli.__version__
diff --git a/cecli/website/docs/config/tui.md b/cecli/website/docs/config/tui.md
index c3f4f9e05b0..5710bfd70e9 100644
--- a/cecli/website/docs/config/tui.md
+++ b/cecli/website/docs/config/tui.md
@@ -46,8 +46,8 @@ tui-config:
dark: true
input-cursor-text-style: "underline"
key_bindings:
- newline: "enter"
- submit: "shift+enter"
+ newline: "shift+enter"
+ submit: "enter"
completion: "tab"
stop: "escape"
cycle_forward: "tab"
@@ -65,8 +65,8 @@ The TUI provides customizable key bindings for all major actions. The default ke
| Action | Default Key | Description |
|--------|-------------|-------------|
-| New Line | `enter` (multiline mode) / `shift+enter` (single-line mode) | Insert a new line in the input area |
-| Submit | `shift+enter` (multiline mode) / `enter` (single-line mode) | Submit the current input |
+| New Line | `shift+enter` | Insert a new line in the input area (internally maps to `ctrl+j` if your editor hates `shift+enter`) |
+| Submit | `enter` | Submit the current input |
| Cancel | `ctrl+c` | Stop and stash current input prompt |
| Stop | `escape` | Interrupt the current LLM response or task |
| Cycle Forward | `tab` | Cycle forward through completion suggestions |
@@ -87,7 +87,7 @@ tui-config:
All key bindings use Textual's key syntax:
- Single keys: `enter`, `escape`, `tab`
-- Modifier combinations: `ctrl+c`, `shift+enter`, etc.
+- Modifier combinations: `ctrl+c`, `shift+tab`, etc.
## Benefits