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
2 changes: 1 addition & 1 deletion cecli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from packaging import version

__version__ = "0.100.8.dev"
__version__ = "0.100.11.dev"
safe_version = __version__

try:
Expand Down
21 changes: 13 additions & 8 deletions cecli/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,10 @@ def get_parser(default_config_files, git_root):
# List of valid edit formats for argparse validation & shtab completion.
# Dynamically gather them from the registered coder classes so the list
# stays in sync if new formats are added.
from cecli import coders as _cecli_coders
from cecli.coders import EDIT_FORMAT_MAP

edit_format_choices = sorted(EDIT_FORMAT_MAP.keys())

edit_format_choices = sorted(
{
c.edit_format
for c in _cecli_coders.__all__
if hasattr(c, "edit_format") and c.edit_format is not None
}
)
group = parser.add_argument_group("Main model")
group.add_argument(
"files", metavar="FILE", nargs="*", help="files to edit with an LLM (optional)"
Expand Down Expand Up @@ -1115,6 +1110,16 @@ def get_parser(default_config_files, git_root):
" specified, a default command for your OS may be used."
),
)
group.add_argument(
"--notification-bell",
action=argparse.BooleanOptionalAction,
default=True,
help=(
"Allow notification commands to produce an audible bell. When enabled, command"
" output is not suppressed so terminal bell escape sequences can ring through"
" (default: True)"
),
)
group.add_argument(
"--command-prefix",
default=None,
Expand Down
20 changes: 20 additions & 0 deletions cecli/coders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,26 @@
}


EDIT_FORMAT_MAP = {
"help": "HelpCoder",
"ask": "AskCoder",
"diff": "EditBlockCoder",
"diff-fenced": "EditBlockFencedCoder",
"whole": "WholeFileCoder",
"patch": "PatchCoder",
"udiff": "UnifiedDiffCoder",
"udiff-simple": "UnifiedDiffSimpleCoder",
"architect": "ArchitectCoder",
"editor-diff": "EditorEditBlockCoder",
"editor-whole": "EditorWholeFileCoder",
"editor-diff-fenced": "EditorDiffFencedCoder",
"context": "ContextCoder",
"agent": "AgentCoder",
"hashline": "HashLineCoder",
"subagent": "SubAgentCoder",
}


def __getattr__(name):
if name in _MODULE_MAP:
import importlib
Expand Down
33 changes: 8 additions & 25 deletions cecli/coders/base_coder.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,28 +105,6 @@ def wrap_fence(name):
wrap_fence("sourcecode"),
]

# Map of edit_format values to coder class names.
# Used by Coder.create() to find the right coder class by edit_format
# without importing all coder modules.
EDIT_FORMAT_MAP = {
"help": "HelpCoder",
"ask": "AskCoder",
"diff": "EditBlockCoder",
"diff-fenced": "EditBlockFencedCoder",
"whole": "WholeFileCoder",
"patch": "PatchCoder",
"udiff": "UnifiedDiffCoder",
"udiff-simple": "UnifiedDiffSimpleCoder",
"architect": "ArchitectCoder",
"editor-diff": "EditorEditBlockCoder",
"editor-whole": "EditorWholeFileCoder",
"editor-diff-fenced": "EditorDiffFencedCoder",
"context": "ContextCoder",
"agent": "AgentCoder",
"hashline": "HashLineCoder",
"subagent": "SubAgentCoder",
}


class UsageMeta(type):
"""Metaclass that provides shared accumulator properties across all Coder subclasses.
Expand Down Expand Up @@ -336,6 +314,7 @@ async def create(
uuid=from_coder.uuid,
parent_uuid=from_coder.parent_uuid,
repo=from_coder.repo,
summarizer=from_coder.summarizer,
)
use_kwargs.update(update) # override to complete the switch
use_kwargs.update(kwargs) # override passed kwargs
Expand All @@ -351,7 +330,7 @@ async def create(
res = coders.CopyPasteCoder(main_model, io, args=args, **kwargs)

if not res:
coder_name = EDIT_FORMAT_MAP.get(edit_format)
coder_name = coders.EDIT_FORMAT_MAP.get(edit_format)
if coder_name:
coder_cls = getattr(coders, coder_name)
res = coder_cls(main_model, io, args=args, **kwargs)
Expand All @@ -373,10 +352,14 @@ async def create(

await res.initialize_mcp_tools()

res.original_kwargs = dict(kwargs)
# Store only small/primitive kwargs to avoid retaining large object references.
# Large objects (repo, mcp_manager, commands, summarizer, file_watcher, etc.)
# are either overridden during clone() or accessible from instance attributes.
_LARGE_KWARGS = {"repo", "mcp_manager", "commands", "summarizer", "file_watcher"}
res.original_kwargs = {k: v for k, v in kwargs.items() if k not in _LARGE_KWARGS}
return res

valid_formats = list(EDIT_FORMAT_MAP.keys())
valid_formats = list(coders.EDIT_FORMAT_MAP.keys())
raise UnknownEditFormat(edit_format, valid_formats)

async def clone(self, **kwargs):
Expand Down
Loading
Loading