diff --git a/Juliet/include/Core/Common/String.h b/Juliet/include/Core/Common/String.h index ec18cef..b84d519 100644 --- a/Juliet/include/Core/Common/String.h +++ b/Juliet/include/Core/Common/String.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -67,12 +68,9 @@ namespace Juliet size_t length = 0; if (str) { - while (char ch = *str) + while (*str) { - if ((ch & 0xC0) != 0x80) - { - ++length; - } + ++length; ++str; } } @@ -89,7 +87,7 @@ namespace Juliet { String result = {}; result.Data = const_cast(str); - result.Size = StringLength(str); + result.Size = str ? strlen(str) : 0; return result; } diff --git a/Romeo/docs/overview.md b/Romeo/docs/overview.md index b302c0a..019a23a 100644 --- a/Romeo/docs/overview.md +++ b/Romeo/docs/overview.md @@ -32,4 +32,75 @@ This is an auto-generated index of all C++ sources in the workspace. - [C:\Dev\Classified\Juliet\Juliet\include\Core\Logging\LogManager](C__Dev_Classified_Juliet_Juliet_include_Core_Logging_LogManager.md) - [C:\Dev\Classified\Juliet\Juliet\src\Core\Math\MathRound](C__Dev_Classified_Juliet_Juliet_src_Core_Math_MathRound.md) - [C:\Dev\Classified\Juliet\Juliet\include\Core\Memory\Allocator](C__Dev_Classified_Juliet_Juliet_include_Core_Memory_Allocator.md) -- [C:\Dev\Classified\Juliet\Juliet\include\Core\Memory\MemoryArena](C__Dev_Classified_Juliet_Juliet_include_Co \ No newline at end of file +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Memory\MemoryArena](C__Dev_Classified_Juliet_Juliet_include_Core_Memory_MemoryArena.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Memory\MemoryArenaDebug](C__Dev_Classified_Juliet_Juliet_include_Core_Memory_MemoryArenaDebug.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Core\Memory\MemoryArenaTests](C__Dev_Classified_Juliet_Juliet_src_Core_Memory_MemoryArenaTests.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Memory\ScratchArena](C__Dev_Classified_Juliet_Juliet_include_Core_Memory_ScratchArena.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Networking\NetworkPacket](C__Dev_Classified_Juliet_Juliet_include_Core_Networking_NetworkPacket.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Networking\Socket](C__Dev_Classified_Juliet_Juliet_include_Core_Networking_Socket.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Networking\TcpListener](C__Dev_Classified_Juliet_Juliet_include_Core_Networking_TcpListener.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Networking\TcpSocket](C__Dev_Classified_Juliet_Juliet_include_Core_Networking_TcpSocket.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Core\Networking\Win32\Win32SocketPlatformImpl](C__Dev_Classified_Juliet_Juliet_src_Core_Networking_Win32_Win32SocketPlatformImpl.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Engine\Debug\MemoryDebugger](C__Dev_Classified_Juliet_Juliet_include_Engine_Debug_MemoryDebugger.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Engine\Engine](C__Dev_Classified_Juliet_Juliet_include_Engine_Engine.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_property_format_table](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_AgilitySDK_d3dx12_d3dx12_property_format_table.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12Buffer](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12Buffer.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12CommandList](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12CommandList.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12Common](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12Common.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12DescriptorHeap](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12DescriptorHeap.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12GraphicsDevice](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12GraphicsDevice.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12GraphicsPipeline](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12GraphicsPipeline.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12InternalTests](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12InternalTests.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12RenderPass](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12RenderPass.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12Shader](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12Shader.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12SwapChain](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12SwapChain.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12Synchronization](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12Synchronization.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12Texture](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12Texture.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\D3D12\D3D12Utils](C__Dev_Classified_Juliet_Juliet_src_Graphics_D3D12_D3D12Utils.md) +- [C:\Dev\Classified\Juliet\Juliet\src\Graphics\DebugDisplayRenderer](C__Dev_Classified_Juliet_Juliet_src_Graphics_DebugDisplayRenderer.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\Graphics](C__Dev_Classified_Juliet_Juliet_include_Graphics_Graphics.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\ImGuiRenderer](C__Dev_Classified_Juliet_Juliet_include_Graphics_ImGuiRenderer.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\Mesh](C__Dev_Classified_Juliet_Juliet_include_Graphics_Mesh.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\MeshRenderer](C__Dev_Classified_Juliet_Juliet_include_Graphics_MeshRenderer.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\SkyboxRenderer](C__Dev_Classified_Juliet_Juliet_include_Graphics_SkyboxRenderer.md) +- [C:\Dev\Classified\Juliet\Juliet\src\UnitTest\Container\VectorUnitTest](C__Dev_Classified_Juliet_Juliet_src_UnitTest_Container_VectorUnitTest.md) +- [C:\Dev\Classified\Juliet\Juliet\src\UnitTest\RunUnitTests](C__Dev_Classified_Juliet_Juliet_src_UnitTest_RunUnitTests.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Application\IApplication](C__Dev_Classified_Juliet_Juliet_include_Core_Application_IApplication.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Common\CoreTypes](C__Dev_Classified_Juliet_Juliet_include_Core_Common_CoreTypes.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Common\CRC32](C__Dev_Classified_Juliet_Juliet_include_Core_Common_CRC32.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Common\EnumUtils](C__Dev_Classified_Juliet_Juliet_include_Core_Common_EnumUtils.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Common\NonCopyable](C__Dev_Classified_Juliet_Juliet_include_Core_Common_NonCopyable.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Common\NonMovable](C__Dev_Classified_Juliet_Juliet_include_Core_Common_NonMovable.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Common\NonNullPtr](C__Dev_Classified_Juliet_Juliet_include_Core_Common_NonNullPtr.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Common\Singleton](C__Dev_Classified_Juliet_Juliet_include_Core_Common_Singleton.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\HAL\DynLib\DynamicLibrary](C__Dev_Classified_Juliet_Juliet_include_Core_HAL_DynLib_DynamicLibrary.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\HAL\Keyboard\Keyboard](C__Dev_Classified_Juliet_Juliet_include_Core_HAL_Keyboard_Keyboard.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\HAL\Keyboard\KeyCode](C__Dev_Classified_Juliet_Juliet_include_Core_HAL_Keyboard_KeyCode.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\HAL\Keyboard\ScanCode](C__Dev_Classified_Juliet_Juliet_include_Core_HAL_Keyboard_ScanCode.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\HAL\Mouse\Mouse](C__Dev_Classified_Juliet_Juliet_include_Core_HAL_Mouse_Mouse.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\JulietInit](C__Dev_Classified_Juliet_Juliet_include_Core_JulietInit.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Logging\LogTypes](C__Dev_Classified_Juliet_Juliet_include_Core_Logging_LogTypes.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Main](C__Dev_Classified_Juliet_Juliet_include_Core_Main.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Math\MathUtils](C__Dev_Classified_Juliet_Juliet_include_Core_Math_MathUtils.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Math\Matrix](C__Dev_Classified_Juliet_Juliet_include_Core_Math_Matrix.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Math\Shape](C__Dev_Classified_Juliet_Juliet_include_Core_Math_Shape.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Math\Vector](C__Dev_Classified_Juliet_Juliet_include_Core_Math_Vector.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Memory\Utils](C__Dev_Classified_Juliet_Juliet_include_Core_Memory_Utils.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Networking\IPAddress](C__Dev_Classified_Juliet_Juliet_include_Core_Networking_IPAddress.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Networking\SocketHandle](C__Dev_Classified_Juliet_Juliet_include_Core_Networking_SocketHandle.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Thread\Mutex](C__Dev_Classified_Juliet_Juliet_include_Core_Thread_Mutex.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Core\Thread\Thread](C__Dev_Classified_Juliet_Juliet_include_Core_Thread_Thread.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Engine\Class](C__Dev_Classified_Juliet_Juliet_include_Engine_Class.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\Camera](C__Dev_Classified_Juliet_Juliet_include_Graphics_Camera.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\Colors](C__Dev_Classified_Juliet_Juliet_include_Graphics_Colors.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\DebugDisplay](C__Dev_Classified_Juliet_Juliet_include_Graphics_DebugDisplay.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\GraphicsBuffer](C__Dev_Classified_Juliet_Juliet_include_Graphics_GraphicsBuffer.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\GraphicsConfig](C__Dev_Classified_Juliet_Juliet_include_Graphics_GraphicsConfig.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\GraphicsPipeline](C__Dev_Classified_Juliet_Juliet_include_Graphics_GraphicsPipeline.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\Lighting](C__Dev_Classified_Juliet_Juliet_include_Graphics_Lighting.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\PushConstants](C__Dev_Classified_Juliet_Juliet_include_Graphics_PushConstants.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\RenderPass](C__Dev_Classified_Juliet_Juliet_include_Graphics_RenderPass.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\Shader](C__Dev_Classified_Juliet_Juliet_include_Graphics_Shader.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\Texture](C__Dev_Classified_Juliet_Juliet_include_Graphics_Texture.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Graphics\VertexData](C__Dev_Classified_Juliet_Juliet_include_Graphics_VertexData.md) +- [C:\Dev\Classified\Juliet\Juliet\include\Juliet](C__Dev_Classified_Juliet_Juliet_include_Juliet.md) diff --git a/Romeo/docs/romeo.db b/Romeo/docs/romeo.db index b94bb75..642bef7 100644 Binary files a/Romeo/docs/romeo.db and b/Romeo/docs/romeo.db differ diff --git a/Romeo/src/AiGenerator.cpp b/Romeo/src/AiGenerator.cpp index 1051d91..b049cec 100644 --- a/Romeo/src/AiGenerator.cpp +++ b/Romeo/src/AiGenerator.cpp @@ -113,8 +113,8 @@ namespace Romeo { size_t bodyCap = modelName.Size + 64; char* showBodyBuf = Juliet::ArenaPushArray(arena, bodyCap JULIET_DEBUG_PARAM("ShowBody")); - snprintf(showBodyBuf, bodyCap, "{\"name\":\"%.*s\"}", static_cast(modelName.Size), CStr(modelName)); - Juliet::String showBody = Juliet::WrapString(showBodyBuf); + int showLen = snprintf(showBodyBuf, bodyCap, "{\"name\":\"%.*s\"}", static_cast(modelName.Size), CStr(modelName)); + Juliet::String showBody = { showBodyBuf, static_cast(showLen > 0 ? showLen : 0) }; Juliet::String showResponse = {}; bool showSuccess = PostWithRetry(arena, host, port, ConstString("/api/show"), false, showBody, showResponse); @@ -148,8 +148,8 @@ namespace Romeo OutputDebugStringA("Romeo AI: Model not found. Pulling model...\n"); char* pullBodyBuf = Juliet::ArenaPushArray(arena, bodyCap + 32 JULIET_DEBUG_PARAM("PullBody")); - snprintf(pullBodyBuf, bodyCap + 32, "{\"name\":\"%.*s\",\"stream\":false}", static_cast(modelName.Size), CStr(modelName)); - Juliet::String pullBody = Juliet::WrapString(pullBodyBuf); + int pullLen = snprintf(pullBodyBuf, bodyCap + 32, "{\"name\":\"%.*s\",\"stream\":false}", static_cast(modelName.Size), CStr(modelName)); + Juliet::String pullBody = { pullBodyBuf, static_cast(pullLen > 0 ? pullLen : 0) }; Juliet::String pullResponse = {}; bool pullSuccess = PostWithRetry(arena, host, port, ConstString("/api/pull"), false, pullBody, pullResponse); @@ -225,7 +225,7 @@ namespace Romeo ); } - Juliet::String prompt = { promptBuf, static_cast(written) }; + Juliet::String prompt = { promptBuf, static_cast(written > 0 ? written : 0) }; Juliet::String escapedPrompt = Json_EscapeString(arena, prompt); // Try local Ollama @@ -236,7 +236,7 @@ namespace Romeo Juliet::String modelName = GetEnvironmentVar(arena, "ROMEO_LLM_MODEL"); if (modelName.Size == 0) { - modelName = ConstString("qwen3.5:4b"); + modelName = ConstString("qwen2.5-coder:1.5b"); } // Check / pull model if needed @@ -252,12 +252,12 @@ namespace Romeo size_t bodyCap = modelName.Size + escapedPrompt.Size + 256; char* bodyBuf = Juliet::ArenaPushArray(arena, bodyCap JULIET_DEBUG_PARAM("OllamaBody")); - snprintf(bodyBuf, bodyCap, - "{\"model\":\"%.*s\",\"prompt\":\"%.*s\",\"stream\":false,\"think\":true}", + int bodyLen = snprintf(bodyBuf, bodyCap, + "{\"model\":\"%.*s\",\"prompt\":\"%.*s\",\"stream\":false}", static_cast(modelName.Size), CStr(modelName), static_cast(escapedPrompt.Size), CStr(escapedPrompt) ); - Juliet::String body = Juliet::WrapString(bodyBuf); + Juliet::String body = { bodyBuf, static_cast(bodyLen > 0 ? bodyLen : 0) }; Juliet::String response = {}; diff --git a/Romeo/src/JsonParser.cpp b/Romeo/src/JsonParser.cpp index ea3d80f..fd4c202 100644 --- a/Romeo/src/JsonParser.cpp +++ b/Romeo/src/JsonParser.cpp @@ -431,15 +431,19 @@ namespace Romeo Assert(arena != nullptr); size_t escLen = 0; - const char* p = CStr(str); - const char* end = p + str.Size; + const unsigned char* p = reinterpret_cast(CStr(str)); + const unsigned char* end = p + str.Size; while (p < end) { - char c = *p; - if (c == '"' || c == '\\' || c == '\n' || c == '\r' || c == '\t') + unsigned char c = *p; + if (c == '"' || c == '\\' || c == '\n' || c == '\r' || c == '\t' || c == '\b' || c == '\f') { escLen += 2; } + else if (c < 32) + { + escLen += 6; + } else { escLen += 1; @@ -449,16 +453,23 @@ namespace Romeo char* buf = Juliet::ArenaPushArray(arena, escLen + 1 JULIET_DEBUG_PARAM("JsonEscapedStr")); char* dst = buf; - p = CStr(str); + p = reinterpret_cast(CStr(str)); while (p < end) { - char c = *p; + unsigned char c = *p; if (c == '"') { *dst++ = '\\'; *dst++ = '"'; } else if (c == '\\') { *dst++ = '\\'; *dst++ = '\\'; } else if (c == '\n') { *dst++ = '\\'; *dst++ = 'n'; } else if (c == '\r') { *dst++ = '\\'; *dst++ = 'r'; } else if (c == '\t') { *dst++ = '\\'; *dst++ = 't'; } - else { *dst++ = c; } + else if (c == '\b') { *dst++ = '\\'; *dst++ = 'b'; } + else if (c == '\f') { *dst++ = '\\'; *dst++ = 'f'; } + else if (c < 32) + { + snprintf(dst, 7, "\\u00%02x", static_cast(c)); + dst += 6; + } + else { *dst++ = static_cast(c); } p++; } *dst = '\0'; diff --git a/Romeo/src/MarkdownGenerator.cpp b/Romeo/src/MarkdownGenerator.cpp index e42ab43..cefd56f 100644 --- a/Romeo/src/MarkdownGenerator.cpp +++ b/Romeo/src/MarkdownGenerator.cpp @@ -110,11 +110,37 @@ namespace Romeo { const char* absPtr = CStr(absolutePath); const char* rootPtr = CStr(workspaceRoot); - if (_strnicmp(absPtr, rootPtr, workspaceRoot.Size) == 0) + size_t rootSize = workspaceRoot.Size; + + size_t matched = 0; + while (matched < rootSize && matched < absolutePath.Size) { - const char* rel = absPtr + workspaceRoot.Size; - size_t newSize = absolutePath.Size - workspaceRoot.Size; - if (*rel == '\\' || *rel == '/') { rel++; newSize--; } + char c1 = absPtr[matched]; + char c2 = rootPtr[matched]; + if (c1 == '/') + { + c1 = '\\'; + } + if (c2 == '/') + { + c2 = '\\'; + } + if (tolower(static_cast(c1)) != tolower(static_cast(c2))) + { + break; + } + matched++; + } + + if (matched == rootSize) + { + const char* rel = absPtr + rootSize; + size_t newSize = absolutePath.Size - rootSize; + if (*rel == '\\' || *rel == '/') + { + rel++; + newSize--; + } return { const_cast(rel), newSize }; } } @@ -845,6 +871,25 @@ namespace Romeo { EnsureDirectoryExists(CStr(docsDir)); + // Clean up any stale broken C__*.md files from prior runs + { + char searchPattern[512]; + snprintf(searchPattern, sizeof(searchPattern), "%s\\C__*.md", CStr(docsDir)); + + WIN32_FIND_DATAA findData; + HANDLE hFind = FindFirstFileA(searchPattern, &findData); + if (hFind != INVALID_HANDLE_VALUE) + { + do + { + char filePath[512]; + snprintf(filePath, sizeof(filePath), "%s\\%s", CStr(docsDir), findData.cFileName); + DeleteFileA(filePath); + } while (FindNextFileA(hFind, &findData) != 0); + FindClose(hFind); + } + } + char overviewPath[512]; snprintf(overviewPath, sizeof(overviewPath), "%s\\overview.md", CStr(docsDir)); diff --git a/Romeo/src/main.cpp b/Romeo/src/main.cpp index d9a6534..7e3ccfa 100644 --- a/Romeo/src/main.cpp +++ b/Romeo/src/main.cpp @@ -36,15 +36,32 @@ static Juliet::String GetWorkspaceRoot(Juliet::Arena* arena) char* buf = Juliet::ArenaPushArray(arena, base.Size + 1 JULIET_DEBUG_PARAM("WorkspaceRootPath")); memcpy(buf, base.Data, base.Size); buf[base.Size] = '\0'; - + + // Normalize slashes + for (size_t i = 0; i < base.Size; ++i) + { + if (buf[i] == '/') + { + buf[i] = '\\'; + } + } + + // Search for \bin to find workspace root + char* binPtr = strstr(buf, "\\bin"); + if (binPtr != nullptr) + { + *binPtr = '\0'; + return { buf, static_cast(binPtr - buf) }; + } + size_t count = 0; for (size_t i = base.Size; i > 0; --i) { size_t idx = i - 1; - if (buf[idx] == '\\' || buf[idx] == '/') + if (buf[idx] == '\\') { count++; - if (count == 3) + if (count == 2) { buf[idx] = '\0'; return { buf, idx }; @@ -332,15 +349,17 @@ int JulietMain(int argc, wchar_t** argv) &jobInfo, sizeof(jobInfo)); } - // Build a mutable command line buffer (CreateProcessA requires mutable string) + // Build a command line for cmd.exe /k so the console window remains open char cmdLine[600] = {}; - snprintf(cmdLine, sizeof(cmdLine), "\"%s\" serve", ollamaPath); + snprintf(cmdLine, sizeof(cmdLine), "cmd.exe /k \"\"%s\" serve\"", ollamaPath); STARTUPINFOA si = {}; si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOW; PROCESS_INFORMATION pi = {}; BOOL createRes = CreateProcessA( - ollamaPath, + nullptr, cmdLine, nullptr, nullptr,