Skip to content

Commit 4b16901

Browse files
committed
feat(tui): add source switching command and release as 0.4.5
- add /source command to inspect and switch active source scope inside TUI - persist selected source to config for consistent behavior across sessions - document /source in README TUI examples - add regression tests for TUI source command - bump package version to 0.4.5
1 parent 05ee168 commit 4b16901

5 files changed

Lines changed: 50 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ Inside the TUI:
181181
```text
182182
/help
183183
/status
184+
/source codex
184185
/watch on
185186
/logs 80
186187
/projects

codeclaw/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""CodeClaw — Export your Claude Code and Codex conversations to Hugging Face."""
22

3-
__version__ = "0.4.4"
3+
__version__ = "0.4.5"

codeclaw/tui/app.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from prompt_toolkit.styles import Style
2525
from prompt_toolkit.widgets import TextArea
2626

27+
from ..cli._helpers import SOURCE_CHOICES
2728
from ..cli.export import _run_export
2829
from ..config import load_config, save_config
2930
from ..daemon import (
@@ -332,6 +333,14 @@ def _register_builtin_commands(self) -> None:
332333
handler=self._cmd_watch,
333334
)
334335
)
336+
self.registry.register(
337+
SlashCommand(
338+
name="source",
339+
help_text="Show or change active source scope",
340+
usage="/source [auto|claude|codex|both|cursor|windsurf|aider|continue|antigravity|vscode|zed|xcode-beta]",
341+
handler=self._cmd_source,
342+
)
343+
)
335344
self.registry.register(
336345
SlashCommand(
337346
name="logs",
@@ -488,6 +497,24 @@ def _cmd_watch(self, _ctx, args: list[str]) -> CommandResult:
488497
return CommandResult(bool(payload.get("ok", True)), "watch resumed")
489498
return CommandResult(False, f"Unknown watch action: {action}")
490499

500+
def _cmd_source(self, _ctx, args: list[str]) -> CommandResult:
501+
if not args:
502+
return CommandResult(True, f"current source: {self.source}")
503+
if len(args) != 1:
504+
return CommandResult(False, "Usage: /source <value>")
505+
candidate = args[0].strip().lower()
506+
if candidate not in SOURCE_CHOICES:
507+
return CommandResult(False, f"Invalid source: {candidate}")
508+
509+
self.source = candidate
510+
cfg = load_config()
511+
if candidate == "auto":
512+
cfg["source"] = None
513+
else:
514+
cfg["source"] = candidate
515+
save_config(cfg)
516+
return CommandResult(True, f"source updated: {candidate}")
517+
491518
def _cmd_logs(self, _ctx, args: list[str]) -> CommandResult:
492519
count = 40
493520
if args:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "codeclaw"
7-
version = "0.4.4"
7+
version = "0.4.5"
88
description = "Export your Claude Code and Codex conversations to Hugging Face as structured training data"
99
requires-python = ">=3.10"
1010
license = "MIT"

tests/test_tui_app.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,23 @@ def test_tui_scope_command_updates_connected_projects(monkeypatch, tmp_path):
6969
invalid = app._cmd_scope(None, ["missing-project"])
7070
assert invalid.ok is False
7171
app.jobs.shutdown()
72+
73+
74+
def test_tui_source_command_updates_config(monkeypatch, tmp_path):
75+
app, cfg = _build_app(monkeypatch, tmp_path, source="auto")
76+
77+
show = app._cmd_source(None, [])
78+
assert show.ok is True
79+
assert "current source: auto" in show.message
80+
81+
set_codex = app._cmd_source(None, ["codex"])
82+
assert set_codex.ok is True
83+
assert cfg["source"] == "codex"
84+
85+
set_auto = app._cmd_source(None, ["auto"])
86+
assert set_auto.ok is True
87+
assert cfg["source"] is None
88+
89+
bad = app._cmd_source(None, ["invalid-source"])
90+
assert bad.ok is False
91+
app.jobs.shutdown()

0 commit comments

Comments
 (0)