diff --git a/packages/claude-code-plugin/hooks/lib/onboarding_tour.py b/packages/claude-code-plugin/hooks/lib/onboarding_tour.py index 8b8eaf8a..9579f4a5 100644 --- a/packages/claude-code-plugin/hooks/lib/onboarding_tour.py +++ b/packages/claude-code-plugin/hooks/lib/onboarding_tour.py @@ -140,13 +140,17 @@ def mark_onboarded() -> None: }, } -TOUR_SKIP: Dict[str, str] = { - "en": "Skip future tours: touch ~/.codingbuddy/onboarded", - "ko": "투어 건너뛰기: touch ~/.codingbuddy/onboarded", - "ja": "ツアーをスキップ: touch ~/.codingbuddy/onboarded", - "zh": "跳过教程: touch ~/.codingbuddy/onboarded", - "es": "Saltar tour: touch ~/.codingbuddy/onboarded", -} +def get_tour_skip_message(lang: str) -> str: + """Generate skip message with actual data dir path.""" + data_dir = resolve_data_dir() + templates = { + "en": f"Skip future tours: touch {data_dir}/onboarded", + "ko": f"투어 건너뛰기: touch {data_dir}/onboarded", + "ja": f"ツアーをスキップ: touch {data_dir}/onboarded", + "zh": f"跳过教程: touch {data_dir}/onboarded", + "es": f"Saltar tour: touch {data_dir}/onboarded", + } + return templates.get(lang, templates["en"]) TOUR_HEADER: Dict[str, str] = { "en": "Quick Tour", @@ -217,6 +221,6 @@ def render_onboarding_tour( lines.append("") lines.append(f"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501") - lines.append(f"\U0001f4ac {_get_text(TOUR_SKIP, language)}") + lines.append(f"\U0001f4ac {get_tour_skip_message(language)}") return "\n".join(lines) diff --git a/packages/claude-code-plugin/tests/test_onboarding_tour.py b/packages/claude-code-plugin/tests/test_onboarding_tour.py index f09f2bc2..984326f2 100644 --- a/packages/claude-code-plugin/tests/test_onboarding_tour.py +++ b/packages/claude-code-plugin/tests/test_onboarding_tour.py @@ -108,9 +108,18 @@ def test_contains_buddy_face(self): assert onboarding_tour.BUDDY_FACE in result def test_contains_skip_message(self): - """Tour output contains skip instructions.""" - result = onboarding_tour.render_onboarding_tour() - assert "~/.codingbuddy/onboarded" in result + """Tour output contains skip instructions with resolved data dir.""" + with patch.dict(os.environ, {}, clear=False): + os.environ.pop("CLAUDE_PLUGIN_DATA", None) + result = onboarding_tour.render_onboarding_tour() + assert "/.codingbuddy/onboarded" in result + + def test_skip_message_uses_custom_data_dir(self): + """Skip message reflects CLAUDE_PLUGIN_DATA when set.""" + with patch.dict(os.environ, {"CLAUDE_PLUGIN_DATA": "/tmp/custom-buddy"}): + result = onboarding_tour.render_onboarding_tour() + assert "/tmp/custom-buddy/onboarded" in result + assert "~/.codingbuddy/onboarded" not in result def test_english_content(self): """English tour contains expected keywords.""" @@ -162,6 +171,35 @@ def test_example_commands_present(self): assert "PLAN add user authentication" in result +class TestGetTourSkipMessage: + """Tests for get_tour_skip_message function.""" + + def test_default_path(self): + """Uses ~/.codingbuddy when CLAUDE_PLUGIN_DATA is not set.""" + with patch.dict(os.environ, {}, clear=False): + os.environ.pop("CLAUDE_PLUGIN_DATA", None) + msg = onboarding_tour.get_tour_skip_message("en") + assert "/.codingbuddy/onboarded" in msg + + def test_custom_data_dir(self): + """Uses CLAUDE_PLUGIN_DATA path when set.""" + with patch.dict(os.environ, {"CLAUDE_PLUGIN_DATA": "/custom/data"}): + msg = onboarding_tour.get_tour_skip_message("en") + assert "/custom/data/onboarded" in msg + + def test_korean_with_custom_dir(self): + """Korean message uses custom path.""" + with patch.dict(os.environ, {"CLAUDE_PLUGIN_DATA": "/my/dir"}): + msg = onboarding_tour.get_tour_skip_message("ko") + assert "/my/dir/onboarded" in msg + assert "투어 건너뛰기" in msg + + def test_unknown_lang_falls_back_to_english(self): + """Unknown language falls back to English.""" + msg = onboarding_tour.get_tour_skip_message("xx") + assert "Skip future tours" in msg + + class TestHelpers: """Tests for internal helper functions."""