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
17 changes: 12 additions & 5 deletions cecli/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,18 @@ def __init__(
self.editor = editor
self.original_read_only_fnames = set(original_read_only_fnames or [])

try:
self.custom_commands = json.loads(getattr(self.args, "command_paths", "[]"))
except (json.JSONDecodeError, TypeError) as e:
self.io.tool_warning(f"Failed to parse command paths JSON: {e}")
self.custom_commands = []
command_paths_raw = getattr(self.args, "command_paths", None)
if isinstance(command_paths_raw, (list, tuple)):
# When the parser already produced a list/tuple, accept it directly
self.custom_commands = list(command_paths_raw)
else:
if command_paths_raw is None:
command_paths_raw = "[]"
try:
self.custom_commands = json.loads(command_paths_raw)
except (json.JSONDecodeError, TypeError) as e:
self.io.tool_warning(f"Failed to parse command paths JSON: {e}")
self.custom_commands = []

# Load custom commands from plugin paths
self._load_custom_commands(self.custom_commands)
Expand Down
11 changes: 11 additions & 0 deletions tests/basic/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import tempfile
from io import StringIO
from pathlib import Path
from types import SimpleNamespace
from unittest import TestCase, mock

import git
Expand Down Expand Up @@ -130,6 +131,16 @@ async def test_cmd_copy_with_cur_messages(self):
# Assert tool_error was called indicating no assistant messages
mock_tool_error.assert_called_once_with("No assistant messages found to copy.")

def test_command_paths_none_does_not_warn(self):
io = InputOutput(pretty=False, fancy_input=False, yes=True)
args = SimpleNamespace(command_paths=None)

with mock.patch.object(io, "tool_warning") as tool_warning:
commands = Commands(io, coder=None, args=args)

self.assertEqual(commands.custom_commands, [])
tool_warning.assert_not_called()

async def test_cmd_copy_pyperclip_exception(self):
io = InputOutput(pretty=False, fancy_input=False, yes=True)
coder = await Coder.create(self.GPT35, None, io)
Expand Down