@@ -1755,6 +1755,77 @@ TEST(search_code_scoped_path_with_spaces_issue687) {
17551755 PASS ();
17561756}
17571757
1758+ #ifdef _WIN32
1759+ /* Issue #903 follow-up: scoped search_code on Windows writes a UTF-8 filelist
1760+ * containing absolute source paths, then reads it back through PowerShell.
1761+ * Windows PowerShell 5.1 treats UTF-8 without BOM as ANSI unless told
1762+ * otherwise, so a non-ASCII project root can be mojibaked before
1763+ * Select-String sees the LiteralPath. */
1764+ TEST (search_code_scoped_path_with_cjk_root_issue903 ) {
1765+ char tmp [512 ];
1766+ snprintf (tmp , sizeof (tmp ), "%s/cbm_srch_cjk_XXXXXX" , cbm_tmpdir ());
1767+ if (!cbm_mkdtemp (tmp )) {
1768+ FAIL ("cbm_mkdtemp failed" );
1769+ }
1770+
1771+ char proj_dir [640 ];
1772+ snprintf (proj_dir , sizeof (proj_dir ), "%s/%s" , tmp ,
1773+ "\xE4\xB8\xAD\xE6\x96\x87\xE9\xA1\xB9\xE7\x9B\xAE" );
1774+ cbm_mkdir (proj_dir );
1775+
1776+ char src_path [768 ];
1777+ snprintf (src_path , sizeof (src_path ), "%s/main.go" , proj_dir );
1778+ FILE * fp = cbm_fopen (src_path , "wb" );
1779+ if (!fp ) {
1780+ cbm_rmdir (proj_dir );
1781+ cbm_rmdir (tmp );
1782+ FAIL ("cannot write source file under CJK path" );
1783+ }
1784+ fprintf (fp , "package main\n\nfunc HandleRequest() error {\n\treturn nil\n}\n" );
1785+ fclose (fp );
1786+
1787+ cbm_mcp_server_t * srv = cbm_mcp_server_new (NULL );
1788+ ASSERT_NOT_NULL (srv );
1789+ cbm_store_t * st = cbm_mcp_server_store (srv );
1790+ ASSERT_NOT_NULL (st );
1791+ const char * proj = "cjk-search" ;
1792+ cbm_mcp_server_set_project (srv , proj );
1793+ cbm_store_upsert_project (st , proj , proj_dir );
1794+
1795+ cbm_node_t n = {.project = proj ,
1796+ .label = "Function" ,
1797+ .name = "HandleRequest" ,
1798+ .qualified_name = "cjk-search.main.HandleRequest" ,
1799+ .file_path = "main.go" ,
1800+ .start_line = 3 ,
1801+ .end_line = 5 };
1802+ ASSERT_GT (cbm_store_upsert_node (st , & n ), 0 );
1803+
1804+ char * resp = cbm_mcp_server_handle (
1805+ srv , "{\"jsonrpc\":\"2.0\",\"id\":903,\"method\":\"tools/call\","
1806+ "\"params\":{\"name\":\"search_code\","
1807+ "\"arguments\":{\"pattern\":\"HandleRequest\",\"project\":\"cjk-search\"}}}" );
1808+ ASSERT_NOT_NULL (resp );
1809+ char * inner = extract_text_content (resp );
1810+ ASSERT_NOT_NULL (inner );
1811+
1812+ int grep_matches = -1 ;
1813+ const char * g = strstr (inner , "\"total_grep_matches\":" );
1814+ if (g ) {
1815+ sscanf (g , "\"total_grep_matches\":%d" , & grep_matches );
1816+ }
1817+ ASSERT_TRUE (grep_matches > 0 );
1818+
1819+ free (inner );
1820+ free (resp );
1821+ cbm_mcp_server_free (srv );
1822+ cbm_unlink (src_path );
1823+ cbm_rmdir (proj_dir );
1824+ cbm_rmdir (tmp );
1825+ PASS ();
1826+ }
1827+ #endif
1828+
17581829/* Shared fixture for the path_filter prefilter tests (PR #756 distilled):
17591830 * a project with two indexed files that both contain the search pattern —
17601831 * src/handler.go (inside the filter) and vendor/other.go (outside it). */
@@ -5072,6 +5143,9 @@ SUITE(mcp) {
50725143 RUN_TEST (tool_search_code_no_project );
50735144 RUN_TEST (search_code_multi_word );
50745145 RUN_TEST (search_code_scoped_path_with_spaces_issue687 );
5146+ #ifdef _WIN32
5147+ RUN_TEST (search_code_scoped_path_with_cjk_root_issue903 );
5148+ #endif
50755149 RUN_TEST (search_code_path_filter_prefilter_keeps_matches );
50765150 RUN_TEST (search_code_path_filter_matches_nothing );
50775151 RUN_TEST (search_code_invalid_regex_errors_issue283 );
0 commit comments