Skip to content

Commit 488d1fa

Browse files
committed
feat(cli): launch TUI by default for bare codeclaw
- route plain codeclaw to TUI when no subcommand is provided - preserve legacy root export shortcut when export flags are passed - update docs and add regression tests for default and export-flag dispatch
1 parent 6ceb226 commit 488d1fa

4 files changed

Lines changed: 46 additions & 2 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ codeclaw console --source codex
146146
Full-screen TUI mode:
147147

148148
```bash
149+
codeclaw
150+
# equivalent explicit command:
149151
codeclaw tui --source both
150152
```
151153

codeclaw/cli/__init__.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,23 @@ def _handle_finetune(args: argparse.Namespace) -> None:
148148
handle_finetune(args)
149149

150150

151+
def _resolve_default_command(args: argparse.Namespace) -> str:
152+
"""Resolve the implicit command when no subcommand was provided."""
153+
if args.command:
154+
return args.command
155+
export_intent = bool(
156+
args.output
157+
or args.repo
158+
or args.all_projects
159+
or args.no_thinking
160+
or args.no_push
161+
or args.dry_run
162+
or args.publish_attestation
163+
or getattr(args, "attest_user_approved_publish", False)
164+
)
165+
return "export" if export_intent else "tui"
166+
167+
151168
def main() -> None:
152169
COMMAND_HANDLERS = {
153170
"prep": _handle_prep,
@@ -331,7 +348,7 @@ def main() -> None:
331348
help="Additional plugin directory (repeatable)",
332349
)
333350

334-
exp = sub.add_parser("export", help="Export and push (default)")
351+
exp = sub.add_parser("export", help="Export and push datasets")
335352
# Export flags on both the subcommand and root parser so `codeclaw --no-push` works
336353
for target in (exp, parser):
337354
target.add_argument("--output", "-o", type=Path, default=None)
@@ -350,6 +367,6 @@ def main() -> None:
350367
target.add_argument("--attest-user-approved-publish", action="store_true", help=argparse.SUPPRESS)
351368

352369
args = parser.parse_args()
353-
command = args.command or "export"
370+
command = _resolve_default_command(args)
354371
handler = COMMAND_HANDLERS.get(command, _run_export)
355372
handler(args)

docs/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ codeclaw watch --pause # Pause watcher without stopping proc
9191
codeclaw watch --resume # Resume watcher polling
9292
codeclaw watch --switch-project "project" # Scope watcher to one connected project
9393
codeclaw console --source both # Open interactive slash-command console
94+
codeclaw # Open full-screen TUI by default
9495
codeclaw tui --source both # Open full-screen TUI mode
9596
codeclaw update-skill claude # Install/update the codeclaw skill for Claude Code
9697
```

tests/test_new_features.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,30 @@ def _fake_tui(_args):
5757
assert called["tui"] is True
5858

5959

60+
def test_main_default_dispatches_tui(monkeypatch):
61+
called = {"tui": False}
62+
63+
def _fake_tui(_args):
64+
called["tui"] = True
65+
66+
monkeypatch.setattr(codeclaw_cli, "handle_tui", _fake_tui)
67+
monkeypatch.setattr(sys, "argv", ["codeclaw"])
68+
codeclaw_cli.main()
69+
assert called["tui"] is True
70+
71+
72+
def test_main_root_export_flags_still_dispatch_export(monkeypatch):
73+
called = {"export": False}
74+
75+
def _fake_export(_args):
76+
called["export"] = True
77+
78+
monkeypatch.setattr(codeclaw_cli, "_run_export", _fake_export)
79+
monkeypatch.setattr(sys, "argv", ["codeclaw", "--no-push"])
80+
codeclaw_cli.main()
81+
assert called["export"] is True
82+
83+
6084
def test_finetune_requires_experimental(capsys):
6185
with pytest.raises(SystemExit):
6286
finetune.handle_finetune(argparse.Namespace(experimental=False, dataset=None, output=None))

0 commit comments

Comments
 (0)