@@ -1755,6 +1755,80 @@ 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+ if (!cbm_mkdir_p (proj_dir , 0755 )) {
1775+ cbm_rmdir (tmp );
1776+ FAIL ("cannot create CJK project dir" );
1777+ }
1778+
1779+ char src_path [768 ];
1780+ snprintf (src_path , sizeof (src_path ), "%s/main.go" , proj_dir );
1781+ FILE * fp = cbm_fopen (src_path , "wb" );
1782+ if (!fp ) {
1783+ cbm_rmdir (proj_dir );
1784+ cbm_rmdir (tmp );
1785+ FAIL ("cannot write source file under CJK path" );
1786+ }
1787+ fprintf (fp , "package main\n\nfunc HandleRequest() error {\n\treturn nil\n}\n" );
1788+ fclose (fp );
1789+
1790+ cbm_mcp_server_t * srv = cbm_mcp_server_new (NULL );
1791+ ASSERT_NOT_NULL (srv );
1792+ cbm_store_t * st = cbm_mcp_server_store (srv );
1793+ ASSERT_NOT_NULL (st );
1794+ const char * proj = "cjk-search" ;
1795+ cbm_mcp_server_set_project (srv , proj );
1796+ cbm_store_upsert_project (st , proj , proj_dir );
1797+
1798+ cbm_node_t n = {.project = proj ,
1799+ .label = "Function" ,
1800+ .name = "HandleRequest" ,
1801+ .qualified_name = "cjk-search.main.HandleRequest" ,
1802+ .file_path = "main.go" ,
1803+ .start_line = 3 ,
1804+ .end_line = 5 };
1805+ ASSERT_GT (cbm_store_upsert_node (st , & n ), 0 );
1806+
1807+ char * resp = cbm_mcp_server_handle (
1808+ srv , "{\"jsonrpc\":\"2.0\",\"id\":903,\"method\":\"tools/call\","
1809+ "\"params\":{\"name\":\"search_code\","
1810+ "\"arguments\":{\"pattern\":\"HandleRequest\",\"project\":\"cjk-search\"}}}" );
1811+ ASSERT_NOT_NULL (resp );
1812+ char * inner = extract_text_content (resp );
1813+ ASSERT_NOT_NULL (inner );
1814+
1815+ int grep_matches = -1 ;
1816+ const char * g = strstr (inner , "\"total_grep_matches\":" );
1817+ if (g ) {
1818+ sscanf (g , "\"total_grep_matches\":%d" , & grep_matches );
1819+ }
1820+ ASSERT_TRUE (grep_matches > 0 );
1821+
1822+ free (inner );
1823+ free (resp );
1824+ cbm_mcp_server_free (srv );
1825+ cbm_unlink (src_path );
1826+ cbm_rmdir (proj_dir );
1827+ cbm_rmdir (tmp );
1828+ PASS ();
1829+ }
1830+ #endif
1831+
17581832/* Shared fixture for the path_filter prefilter tests (PR #756 distilled):
17591833 * a project with two indexed files that both contain the search pattern —
17601834 * src/handler.go (inside the filter) and vendor/other.go (outside it). */
@@ -5072,6 +5146,9 @@ SUITE(mcp) {
50725146 RUN_TEST (tool_search_code_no_project );
50735147 RUN_TEST (search_code_multi_word );
50745148 RUN_TEST (search_code_scoped_path_with_spaces_issue687 );
5149+ #ifdef _WIN32
5150+ RUN_TEST (search_code_scoped_path_with_cjk_root_issue903 );
5151+ #endif
50755152 RUN_TEST (search_code_path_filter_prefilter_keeps_matches );
50765153 RUN_TEST (search_code_path_filter_matches_nothing );
50775154 RUN_TEST (search_code_invalid_regex_errors_issue283 );
0 commit comments