@tyvm/knowhow 0.0.33 → 0.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/autodoc/plugins/downloader/downloader.mdx +2 -2
- package/benchmarks/.dockerignore +7 -0
- package/benchmarks/README.md +166 -0
- package/benchmarks/docker/Dockerfile +68 -0
- package/benchmarks/example-config.yml +27 -0
- package/benchmarks/jest.config.js +13 -0
- package/benchmarks/package-lock.json +4297 -0
- package/benchmarks/package.json +39 -0
- package/benchmarks/results/4542435/2025-08-05/lms/lms-openai-gpt-oss-20b.json +2814 -0
- package/benchmarks/results/4542435/2025-08-05/lms/lms-qwen-qwen3-30b-a3b-2507.json +2014 -0
- package/benchmarks/results/4fb9125/2025-08-07/anthropic/anthropic-claude-sonnet-4-20250514.json +3121 -0
- package/benchmarks/results/5766aee/2025-08-02/lms-qwen/qwen3-coder-30b.json +98 -0
- package/benchmarks/results/6d73808/2025-08-07/openai/openai-gpt-5.json +3256 -0
- package/benchmarks/results/77bf0a6/2025-08-02/lms-qwen/qwen3-30b-a3b-2507.json +4298 -0
- package/benchmarks/results/8c0d445/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +3031 -0
- package/benchmarks/results/8c0d445/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +2990 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +3256 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +3007 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +3256 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-mini-2025-04-14.json +3036 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-nano-2025-04-14.json +3280 -0
- package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-30b-a3b-2507.json +1920 -0
- package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-coder-30b.json +3281 -0
- package/benchmarks/results/b502ed9/2025-08-03/lms-qwen/qwen3-coder-30b.json +2896 -0
- package/benchmarks/results/d1a8129/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +3011 -0
- package/benchmarks/results/e60471c/2025-08-03/lms/qwen3-30b-a3b-2507.json +3003 -0
- package/benchmarks/scripts/build-and-run.sh +47 -0
- package/benchmarks/scripts/clone-exercism.sh +92 -0
- package/benchmarks/scripts/validate.sh +48 -0
- package/benchmarks/src/__tests__/runner.test.ts +27 -0
- package/benchmarks/src/cli.ts +90 -0
- package/benchmarks/src/evaluators/EvaluatorRegistry.ts +64 -0
- package/benchmarks/src/evaluators/JavaScriptEvaluator.ts +183 -0
- package/benchmarks/src/evaluators/index.ts +3 -0
- package/benchmarks/src/evaluators/types.ts +22 -0
- package/benchmarks/src/index.ts +3 -0
- package/benchmarks/src/providers.ts +13 -0
- package/benchmarks/src/runner.ts +824 -0
- package/benchmarks/src/types.ts +63 -0
- package/benchmarks/tsconfig.json +19 -0
- package/jest.config.js +2 -1
- package/leaderboard/README.md +148 -0
- package/leaderboard/app/api/benchmark-data/route.ts +131 -0
- package/leaderboard/app/api/benchmark-detail/route.ts +172 -0
- package/leaderboard/app/details/[model]/[provider]/[language]/page.tsx +501 -0
- package/leaderboard/app/exercise/[model]/[provider]/[language]/[exercise]/page.tsx +375 -0
- package/leaderboard/app/globals.css +27 -0
- package/leaderboard/app/layout.tsx +21 -0
- package/leaderboard/app/page.tsx +170 -0
- package/leaderboard/components/LeaderboardTable.tsx +168 -0
- package/leaderboard/components/PerformanceChart.tsx +109 -0
- package/leaderboard/next-env.d.ts +5 -0
- package/leaderboard/next.config.js +4 -0
- package/leaderboard/package-lock.json +6363 -0
- package/leaderboard/package.json +28 -0
- package/leaderboard/postcss.config.js +6 -0
- package/leaderboard/tailwind.config.js +17 -0
- package/leaderboard/tsconfig.json +28 -0
- package/leaderboard/types/benchmark.ts +67 -0
- package/leaderboard/utils/dataProcessor.ts +33 -0
- package/package.json +2 -1
- package/src/agents/base/base.ts +147 -21
- package/src/agents/base/prompt.ts +28 -0
- package/src/agents/index.ts +3 -0
- package/src/agents/patcher/patcher.ts +6 -4
- package/src/agents/setup/setup.ts +56 -0
- package/src/agents/tools/agentCall.ts +6 -2
- package/src/agents/tools/aiClient.ts +74 -8
- package/src/agents/tools/execCommand.ts +13 -14
- package/src/agents/tools/executeScript/README.md +16 -0
- package/src/agents/tools/index.ts +2 -0
- package/src/agents/tools/list.ts +73 -16
- package/src/agents/tools/startAgentTask.ts +109 -0
- package/src/agents/tools/textSearch.ts +1 -1
- package/src/agents/tools/visionTool.ts +31 -2
- package/src/agents/tools/ycmd/client.ts +608 -0
- package/src/agents/tools/ycmd/definitions.ts +294 -0
- package/src/agents/tools/ycmd/detection.ts +211 -0
- package/src/agents/tools/ycmd/index.ts +11 -0
- package/src/agents/tools/ycmd/installer.ts +251 -0
- package/src/agents/tools/ycmd/server.ts +535 -0
- package/src/agents/tools/ycmd/serverManager.ts +316 -0
- package/src/agents/tools/ycmd/tools/completion.ts +113 -0
- package/src/agents/tools/ycmd/tools/diagnostics.ts +155 -0
- package/src/agents/tools/ycmd/tools/getLocations.ts +173 -0
- package/src/agents/tools/ycmd/tools/goto.ts +169 -0
- package/src/agents/tools/ycmd/tools/refactor.ts +204 -0
- package/src/agents/tools/ycmd/tools/signature.ts +174 -0
- package/src/agents/tools/ycmd/tools/start.ts +95 -0
- package/src/agents/tools/ycmd/utils/pathUtils.ts +59 -0
- package/src/ai.ts +15 -0
- package/src/chat/CliChatService.ts +277 -0
- package/src/chat/modules/AgentModule.ts +980 -0
- package/src/chat/modules/AskModule.ts +98 -0
- package/src/chat/modules/BaseChatModule.ts +66 -0
- package/src/chat/modules/InternalChatModule.ts +174 -0
- package/src/chat/modules/SearchModule.ts +166 -0
- package/src/chat/modules/SetupModule.ts +185 -0
- package/src/chat/modules/SystemModule.ts +120 -0
- package/src/chat/modules/VoiceModule.ts +70 -0
- package/src/chat/modules/index.js +5 -0
- package/src/chat/types.ts +97 -0
- package/src/chat.ts +9 -1
- package/src/chat2.ts +62 -0
- package/src/cli.ts +264 -35
- package/src/clients/anthropic.ts +14 -7
- package/src/clients/gemini.ts +15 -7
- package/src/clients/http.ts +17 -7
- package/src/clients/index.ts +117 -4
- package/src/clients/knowhow.ts +7 -2
- package/src/clients/knowhowMcp.ts +118 -0
- package/src/clients/openai.ts +32 -8
- package/src/clients/types.ts +1 -0
- package/src/clients/xai.ts +17 -5
- package/src/config.ts +30 -5
- package/src/conversion.ts +4 -1
- package/src/login.ts +26 -9
- package/src/microphone.ts +0 -1
- package/src/plugins/downloader/downloader.ts +72 -24
- package/src/plugins/downloader/plugin.ts +3 -1
- package/src/plugins/plugins.ts +3 -0
- package/src/processors/CustomVariables.ts +425 -0
- package/src/processors/HarmonyToolProcessor.ts +264 -0
- package/src/processors/XmlToolCallProcessor.ts +533 -0
- package/src/processors/index.ts +3 -0
- package/src/prompts/KnowhowConfigExamples.ts +376 -0
- package/src/services/KnowhowClient.ts +49 -3
- package/src/services/Mcp.ts +42 -3
- package/src/services/McpServer.ts +14 -4
- package/src/services/McpWebsocketTransport.ts +21 -7
- package/src/services/MessageProcessor.ts +10 -5
- package/src/services/index.ts +5 -0
- package/src/services/script-execution/ScriptExecutor.ts +34 -1
- package/src/services/types.ts +17 -14
- package/src/types.ts +17 -0
- package/src/utils/index.ts +138 -0
- package/tests/XmlToolCallProcessor.test.ts +468 -0
- package/tests/manual/ycmd/debug_diagnostics_test.ts +127 -0
- package/tests/manual/ycmd/fixtures/debug_diagnostics.ts +26 -0
- package/tests/manual/ycmd/fixtures/file_change_test.ts +17 -0
- package/tests/manual/ycmd/minimal_advanced_test.ts +108 -0
- package/tests/manual/ycmd/simple_diagnostics_test.ts +61 -0
- package/tests/manual/ycmd/simple_test.ts +74 -0
- package/tests/manual/ycmd/test-typescript-sample.ts +34 -0
- package/tests/manual/ycmd/test_advanced_features.ts +407 -0
- package/tests/manual/ycmd/test_advanced_with_tools.ts +320 -0
- package/tests/manual/ycmd/test_comprehensive_typescript.ts +179 -0
- package/tests/manual/ycmd/test_diagnostics_file_changes.ts +249 -0
- package/tests/manual/ycmd/test_diagnostics_fix.ts +99 -0
- package/tests/manual/ycmd/test_diagnostics_simple.ts +100 -0
- package/tests/manual/ycmd/test_diagnostics_timing.ts +120 -0
- package/tests/manual/ycmd/test_discover_commands.ts +310 -0
- package/tests/manual/ycmd/test_endpoints.ts +115 -0
- package/tests/manual/ycmd/test_final_comprehensive.ts +218 -0
- package/tests/manual/ycmd/test_final_validation.ts +150 -0
- package/tests/manual/ycmd/test_implementation.js +42 -0
- package/tests/manual/ycmd/test_individual_ycmd_tool.ts +39 -0
- package/tests/manual/ycmd/test_server_manager.ts +52 -0
- package/tests/manual/ycmd/test_simple_debug.ts +86 -0
- package/tests/manual/ycmd/test_tsserver_workflow.js +83 -0
- package/tests/manual/ycmd/test_tsserver_workflow.ts +122 -0
- package/tests/manual/ycmd/test_typescript_simple.ts +48 -0
- package/tests/manual/ycmd/test_typescript_ycmd.ts +105 -0
- package/tests/manual/ycmd/test_workspace_config.ts +90 -0
- package/tests/manual/ycmd/test_ycmd_auto_start.ts +137 -0
- package/tests/manual/ycmd/test_ycmd_comprehensive.ts +73 -0
- package/tests/manual/ycmd/test_ycmd_connection.py +10 -0
- package/tests/manual/ycmd/test_ycmd_direct.ts +142 -0
- package/tests/manual/ycmd/test_ycmd_experiment.ts +48 -0
- package/tests/manual/ycmd/test_ycmd_final.ts +200 -0
- package/tests/manual/ycmd/test_ycmd_fixed.py +18 -0
- package/tests/manual/ycmd/test_ycmd_integration.ts +112 -0
- package/tests/manual/ycmd/test_ycmd_simple.ts +45 -0
- package/tests/manual/ycmd/test_ycmd_usage.py +27 -0
- package/tests/manual/ycmd/working_simple_test.ts +134 -0
- package/ts_build/src/agents/base/base.d.ts +14 -1
- package/ts_build/src/agents/base/base.js +91 -17
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/base/prompt.d.ts +1 -1
- package/ts_build/src/agents/base/prompt.js +28 -0
- package/ts_build/src/agents/base/prompt.js.map +1 -1
- package/ts_build/src/agents/index.d.ts +2 -0
- package/ts_build/src/agents/index.js +2 -0
- package/ts_build/src/agents/index.js.map +1 -1
- package/ts_build/src/agents/patcher/patcher.js +6 -3
- package/ts_build/src/agents/patcher/patcher.js.map +1 -1
- package/ts_build/src/agents/setup/setup.d.ts +8 -0
- package/ts_build/src/agents/setup/setup.js +59 -0
- package/ts_build/src/agents/setup/setup.js.map +1 -0
- package/ts_build/src/agents/tools/agentCall.js +5 -2
- package/ts_build/src/agents/tools/agentCall.js.map +1 -1
- package/ts_build/src/agents/tools/aiClient.d.ts +6 -5
- package/ts_build/src/agents/tools/aiClient.js +37 -6
- package/ts_build/src/agents/tools/aiClient.js.map +1 -1
- package/ts_build/src/agents/tools/execCommand.d.ts +2 -2
- package/ts_build/src/agents/tools/execCommand.js +5 -6
- package/ts_build/src/agents/tools/execCommand.js.map +1 -1
- package/ts_build/src/agents/tools/executeScript/index.d.ts +1 -1
- package/ts_build/src/agents/tools/index.d.ts +2 -0
- package/ts_build/src/agents/tools/index.js +2 -0
- package/ts_build/src/agents/tools/index.js.map +1 -1
- package/ts_build/src/agents/tools/list.js +66 -16
- package/ts_build/src/agents/tools/list.js.map +1 -1
- package/ts_build/src/agents/tools/startAgentTask.d.ts +13 -0
- package/ts_build/src/agents/tools/startAgentTask.js +74 -0
- package/ts_build/src/agents/tools/startAgentTask.js.map +1 -0
- package/ts_build/src/agents/tools/startChatTask.d.ts +13 -0
- package/ts_build/src/agents/tools/startChatTask.js +73 -0
- package/ts_build/src/agents/tools/startChatTask.js.map +1 -0
- package/ts_build/src/agents/tools/textSearch.js +1 -1
- package/ts_build/src/agents/tools/textSearch.js.map +1 -1
- package/ts_build/src/agents/tools/visionTool.d.ts +1 -1
- package/ts_build/src/agents/tools/visionTool.js +23 -3
- package/ts_build/src/agents/tools/visionTool.js.map +1 -1
- package/ts_build/src/agents/tools/ycmd/client.d.ts +93 -0
- package/ts_build/src/agents/tools/ycmd/client.js +355 -0
- package/ts_build/src/agents/tools/ycmd/client.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/definitions.d.ts +345 -0
- package/ts_build/src/agents/tools/ycmd/definitions.js +298 -0
- package/ts_build/src/agents/tools/ycmd/definitions.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/detection.d.ts +11 -0
- package/ts_build/src/agents/tools/ycmd/detection.js +175 -0
- package/ts_build/src/agents/tools/ycmd/detection.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/index.d.ts +8 -0
- package/ts_build/src/agents/tools/ycmd/index.js +20 -0
- package/ts_build/src/agents/tools/ycmd/index.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/installer.d.ts +19 -0
- package/ts_build/src/agents/tools/ycmd/installer.js +196 -0
- package/ts_build/src/agents/tools/ycmd/installer.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/server.d.ts +35 -0
- package/ts_build/src/agents/tools/ycmd/server.js +363 -0
- package/ts_build/src/agents/tools/ycmd/server.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/serverManager.d.ts +39 -0
- package/ts_build/src/agents/tools/ycmd/serverManager.js +210 -0
- package/ts_build/src/agents/tools/ycmd/serverManager.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/completion.d.ts +22 -0
- package/ts_build/src/agents/tools/ycmd/tools/completion.js +72 -0
- package/ts_build/src/agents/tools/ycmd/tools/completion.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/diagnostics.d.ts +42 -0
- package/ts_build/src/agents/tools/ycmd/tools/diagnostics.js +88 -0
- package/ts_build/src/agents/tools/ycmd/tools/diagnostics.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/getLocations.d.ts +22 -0
- package/ts_build/src/agents/tools/ycmd/tools/getLocations.js +142 -0
- package/ts_build/src/agents/tools/ycmd/tools/getLocations.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/goto.d.ts +20 -0
- package/ts_build/src/agents/tools/ycmd/tools/goto.js +101 -0
- package/ts_build/src/agents/tools/ycmd/tools/goto.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/refactor.d.ts +32 -0
- package/ts_build/src/agents/tools/ycmd/tools/refactor.js +123 -0
- package/ts_build/src/agents/tools/ycmd/tools/refactor.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/signature.d.ts +25 -0
- package/ts_build/src/agents/tools/ycmd/tools/signature.js +110 -0
- package/ts_build/src/agents/tools/ycmd/tools/signature.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/start.d.ts +17 -0
- package/ts_build/src/agents/tools/ycmd/tools/start.js +65 -0
- package/ts_build/src/agents/tools/ycmd/tools/start.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/utils/pathUtils.d.ts +4 -0
- package/ts_build/src/agents/tools/ycmd/utils/pathUtils.js +67 -0
- package/ts_build/src/agents/tools/ycmd/utils/pathUtils.js.map +1 -0
- package/ts_build/src/ai.d.ts +1 -0
- package/ts_build/src/ai.js +40 -1
- package/ts_build/src/ai.js.map +1 -1
- package/ts_build/src/chat/ChatCommandHandler.d.ts +36 -0
- package/ts_build/src/chat/ChatCommandHandler.js +268 -0
- package/ts_build/src/chat/ChatCommandHandler.js.map +1 -0
- package/ts_build/src/chat/ChatInputManager.d.ts +22 -0
- package/ts_build/src/chat/ChatInputManager.js +85 -0
- package/ts_build/src/chat/ChatInputManager.js.map +1 -0
- package/ts_build/src/chat/ChatManager.d.ts +49 -0
- package/ts_build/src/chat/ChatManager.js +271 -0
- package/ts_build/src/chat/ChatManager.js.map +1 -0
- package/ts_build/src/chat/ChatSession.d.ts +32 -0
- package/ts_build/src/chat/ChatSession.js +3 -0
- package/ts_build/src/chat/ChatSession.js.map +1 -0
- package/ts_build/src/chat/ChatSessionManager.d.ts +19 -0
- package/ts_build/src/chat/ChatSessionManager.js +188 -0
- package/ts_build/src/chat/ChatSessionManager.js.map +1 -0
- package/ts_build/src/chat/ChatStateManager.d.ts +58 -0
- package/ts_build/src/chat/ChatStateManager.js +156 -0
- package/ts_build/src/chat/ChatStateManager.js.map +1 -0
- package/ts_build/src/chat/CliChatService.d.ts +35 -0
- package/ts_build/src/chat/CliChatService.js +201 -0
- package/ts_build/src/chat/CliChatService.js.map +1 -0
- package/ts_build/src/chat/InterruptibleInput.d.ts +20 -0
- package/ts_build/src/chat/InterruptibleInput.js +109 -0
- package/ts_build/src/chat/InterruptibleInput.js.map +1 -0
- package/ts_build/src/chat/interfaces/ChatModule.d.ts +6 -0
- package/ts_build/src/chat/interfaces/ChatModule.js +3 -0
- package/ts_build/src/chat/interfaces/ChatModule.js.map +1 -0
- package/ts_build/src/chat/modules/AgentModule.d.ts +56 -0
- package/ts_build/src/chat/modules/AgentModule.js +705 -0
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -0
- package/ts_build/src/chat/modules/AskModule.d.ts +10 -0
- package/ts_build/src/chat/modules/AskModule.js +63 -0
- package/ts_build/src/chat/modules/AskModule.js.map +1 -0
- package/ts_build/src/chat/modules/BaseChatModule.d.ts +14 -0
- package/ts_build/src/chat/modules/BaseChatModule.js +32 -0
- package/ts_build/src/chat/modules/BaseChatModule.js.map +1 -0
- package/ts_build/src/chat/modules/InternalChatModule.d.ts +24 -0
- package/ts_build/src/chat/modules/InternalChatModule.js +127 -0
- package/ts_build/src/chat/modules/InternalChatModule.js.map +1 -0
- package/ts_build/src/chat/modules/SearchModule.d.ts +12 -0
- package/ts_build/src/chat/modules/SearchModule.js +119 -0
- package/ts_build/src/chat/modules/SearchModule.js.map +1 -0
- package/ts_build/src/chat/modules/SetupModule.d.ts +15 -0
- package/ts_build/src/chat/modules/SetupModule.js +147 -0
- package/ts_build/src/chat/modules/SetupModule.js.map +1 -0
- package/ts_build/src/chat/modules/SystemModule.d.ts +14 -0
- package/ts_build/src/chat/modules/SystemModule.js +90 -0
- package/ts_build/src/chat/modules/SystemModule.js.map +1 -0
- package/ts_build/src/chat/modules/VoiceModule.d.ts +11 -0
- package/ts_build/src/chat/modules/VoiceModule.js +57 -0
- package/ts_build/src/chat/modules/VoiceModule.js.map +1 -0
- package/ts_build/src/chat/types.d.ts +83 -0
- package/ts_build/src/chat/types.js +3 -0
- package/ts_build/src/chat/types.js.map +1 -0
- package/ts_build/src/chat.js +7 -1
- package/ts_build/src/chat.js.map +1 -1
- package/ts_build/src/chat2.d.ts +3 -0
- package/ts_build/src/chat2.js +47 -0
- package/ts_build/src/chat2.js.map +1 -0
- package/ts_build/src/cli.js +218 -37
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/clients/anthropic.d.ts +5 -2
- package/ts_build/src/clients/anthropic.js +12 -7
- package/ts_build/src/clients/anthropic.js.map +1 -1
- package/ts_build/src/clients/gemini.d.ts +6 -3
- package/ts_build/src/clients/gemini.js +13 -7
- package/ts_build/src/clients/gemini.js.map +1 -1
- package/ts_build/src/clients/http.d.ts +1 -0
- package/ts_build/src/clients/http.js +12 -5
- package/ts_build/src/clients/http.js.map +1 -1
- package/ts_build/src/clients/index.d.ts +10 -0
- package/ts_build/src/clients/index.js +74 -4
- package/ts_build/src/clients/index.js.map +1 -1
- package/ts_build/src/clients/knowhow.d.ts +3 -1
- package/ts_build/src/clients/knowhow.js +8 -2
- package/ts_build/src/clients/knowhow.js.map +1 -1
- package/ts_build/src/clients/knowhowMcp.d.ts +20 -0
- package/ts_build/src/clients/knowhowMcp.js +86 -0
- package/ts_build/src/clients/knowhowMcp.js.map +1 -0
- package/ts_build/src/clients/openai.d.ts +5 -2
- package/ts_build/src/clients/openai.js +29 -8
- package/ts_build/src/clients/openai.js.map +1 -1
- package/ts_build/src/clients/types.d.ts +1 -0
- package/ts_build/src/clients/xai.d.ts +5 -2
- package/ts_build/src/clients/xai.js +15 -5
- package/ts_build/src/clients/xai.js.map +1 -1
- package/ts_build/src/config.js +24 -3
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/conversion.js +6 -4
- package/ts_build/src/conversion.js.map +1 -1
- package/ts_build/src/login.d.ts +1 -1
- package/ts_build/src/login.js +21 -7
- package/ts_build/src/login.js.map +1 -1
- package/ts_build/src/microphone.js.map +1 -1
- package/ts_build/src/plugins/downloader/downloader.d.ts +4 -5
- package/ts_build/src/plugins/downloader/downloader.js +55 -26
- package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
- package/ts_build/src/plugins/downloader/plugin.js +5 -3
- package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
- package/ts_build/src/plugins/plugins.js +3 -0
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/processors/CustomVariables.d.ts +32 -0
- package/ts_build/src/processors/CustomVariables.js +297 -0
- package/ts_build/src/processors/CustomVariables.js.map +1 -0
- package/ts_build/src/processors/HarmonyToolProcessor.d.ts +15 -0
- package/ts_build/src/processors/HarmonyToolProcessor.js +154 -0
- package/ts_build/src/processors/HarmonyToolProcessor.js.map +1 -0
- package/ts_build/src/processors/XmlToolCallProcessor.d.ts +14 -0
- package/ts_build/src/processors/XmlToolCallProcessor.js +357 -0
- package/ts_build/src/processors/XmlToolCallProcessor.js.map +1 -0
- package/ts_build/src/processors/index.d.ts +3 -0
- package/ts_build/src/processors/index.js +7 -1
- package/ts_build/src/processors/index.js.map +1 -1
- package/ts_build/src/prompts/KnowhowConfigExamples.d.ts +2 -0
- package/ts_build/src/prompts/KnowhowConfigExamples.js +379 -0
- package/ts_build/src/prompts/KnowhowConfigExamples.js.map +1 -0
- package/ts_build/src/services/KnowhowClient.d.ts +22 -0
- package/ts_build/src/services/KnowhowClient.js +14 -2
- package/ts_build/src/services/KnowhowClient.js.map +1 -1
- package/ts_build/src/services/Mcp.d.ts +1 -0
- package/ts_build/src/services/Mcp.js +20 -3
- package/ts_build/src/services/Mcp.js.map +1 -1
- package/ts_build/src/services/McpServer.d.ts +1 -1
- package/ts_build/src/services/McpServer.js +8 -4
- package/ts_build/src/services/McpServer.js.map +1 -1
- package/ts_build/src/services/McpWebsocketTransport.js +17 -7
- package/ts_build/src/services/McpWebsocketTransport.js.map +1 -1
- package/ts_build/src/services/MessageProcessor.d.ts +1 -1
- package/ts_build/src/services/MessageProcessor.js +4 -4
- package/ts_build/src/services/MessageProcessor.js.map +1 -1
- package/ts_build/src/services/index.d.ts +2 -0
- package/ts_build/src/services/index.js +4 -0
- package/ts_build/src/services/index.js.map +1 -1
- package/ts_build/src/services/script-execution/ScriptExecutor.d.ts +1 -0
- package/ts_build/src/services/script-execution/ScriptExecutor.js +23 -0
- package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
- package/ts_build/src/services/types.d.ts +2 -6
- package/ts_build/src/services/types.js +4 -4
- package/ts_build/src/services/types.js.map +1 -1
- package/ts_build/src/types.d.ts +11 -0
- package/ts_build/src/types.js +8 -0
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/utils/index.d.ts +2 -0
- package/ts_build/src/utils/index.js +102 -1
- package/ts_build/src/utils/index.js.map +1 -1
- package/ts_build/tests/XmlToolCallProcessor.test.d.ts +1 -0
- package/ts_build/tests/XmlToolCallProcessor.test.js +376 -0
- package/ts_build/tests/XmlToolCallProcessor.test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/debug_diagnostics_test.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/debug_diagnostics_test.js +114 -0
- package/ts_build/tests/manual/ycmd/debug_diagnostics_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/minimal_advanced_test.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/minimal_advanced_test.js +104 -0
- package/ts_build/tests/manual/ycmd/minimal_advanced_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/simple_diagnostics_test.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/simple_diagnostics_test.js +74 -0
- package/ts_build/tests/manual/ycmd/simple_diagnostics_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/simple_test.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/simple_test.js +82 -0
- package/ts_build/tests/manual/ycmd/simple_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test-typescript-sample.d.ts +14 -0
- package/ts_build/tests/manual/ycmd/test-typescript-sample.js +20 -0
- package/ts_build/tests/manual/ycmd/test-typescript-sample.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_advanced_features.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_advanced_features.js +297 -0
- package/ts_build/tests/manual/ycmd/test_advanced_features.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_advanced_with_tools.d.ts +3 -0
- package/ts_build/tests/manual/ycmd/test_advanced_with_tools.js +262 -0
- package/ts_build/tests/manual/ycmd/test_advanced_with_tools.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.js +186 -0
- package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.js +174 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_fix.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_fix.js +106 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_fix.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_simple.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_simple.js +104 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_simple.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_timing.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_timing.js +119 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_timing.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_discover_commands.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_discover_commands.js +243 -0
- package/ts_build/tests/manual/ycmd/test_discover_commands.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_endpoints.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_endpoints.js +120 -0
- package/ts_build/tests/manual/ycmd/test_endpoints.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_final_comprehensive.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_final_comprehensive.js +221 -0
- package/ts_build/tests/manual/ycmd/test_final_comprehensive.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_final_validation.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_final_validation.js +160 -0
- package/ts_build/tests/manual/ycmd/test_final_validation.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.js +37 -0
- package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_server_manager.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_server_manager.js +38 -0
- package/ts_build/tests/manual/ycmd/test_server_manager.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_simple_debug.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_simple_debug.js +99 -0
- package/ts_build/tests/manual/ycmd/test_simple_debug.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_tsserver_workflow.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_tsserver_workflow.js +128 -0
- package/ts_build/tests/manual/ycmd/test_tsserver_workflow.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_simple.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_simple.js +66 -0
- package/ts_build/tests/manual/ycmd/test_typescript_simple.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_ycmd.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_ycmd.js +105 -0
- package/ts_build/tests/manual/ycmd/test_typescript_ycmd.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_workspace_config.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_workspace_config.js +89 -0
- package/ts_build/tests/manual/ycmd/test_workspace_config.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.js +130 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.js +83 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_direct.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_direct.js +149 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_direct.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_experiment.d.ts +15 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_experiment.js +58 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_experiment.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_final.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_final.js +195 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_final.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_integration.d.ts +3 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_integration.js +110 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_integration.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_simple.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_simple.js +36 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_simple.js.map +1 -0
- package/ts_build/tests/manual/ycmd/working_simple_test.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/working_simple_test.js +134 -0
- package/ts_build/tests/manual/ycmd/working_simple_test.js.map +1 -0
- package/tsconfig.json +3 -1
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as crypto from "crypto";
|
|
4
|
+
import * as net from "net";
|
|
5
|
+
import { getConfig } from "../../../config";
|
|
6
|
+
import { spawn, ChildProcess } from "child_process";
|
|
7
|
+
import { YcmdDetection } from "./detection";
|
|
8
|
+
import { YcmdInstaller } from "./installer";
|
|
9
|
+
import { YcmdClient } from "./client";
|
|
10
|
+
|
|
11
|
+
export interface YcmdServerInfo {
|
|
12
|
+
port: number;
|
|
13
|
+
host: string;
|
|
14
|
+
hmacSecret: string;
|
|
15
|
+
pid?: number;
|
|
16
|
+
status: "starting" | "running" | "stopped" | "error";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Manages ycmd server lifecycle
|
|
21
|
+
*/
|
|
22
|
+
export class YcmdServer {
|
|
23
|
+
private process: ChildProcess | null = null;
|
|
24
|
+
private serverInfo: YcmdServerInfo | null = null;
|
|
25
|
+
private hmacSecret: string;
|
|
26
|
+
private ycmdPath: string;
|
|
27
|
+
private configuredPort: number = 0;
|
|
28
|
+
private detectedPort: number | null = null;
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
this.setupExitHandler();
|
|
32
|
+
// Generate a unique HMAC secret for this server instance
|
|
33
|
+
this.hmacSecret = crypto.randomBytes(16).toString("base64");
|
|
34
|
+
// Ensure cleanup when parent process exits
|
|
35
|
+
process.on("exit", () => this.forceCleanup());
|
|
36
|
+
|
|
37
|
+
// Find ycmd installation
|
|
38
|
+
const installations = YcmdDetection.findInstallations();
|
|
39
|
+
if (installations.length === 0) {
|
|
40
|
+
throw new Error("No ycmd installation found. Please install ycmd first.");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Use configured install path or prefer knowhow installation if available
|
|
44
|
+
const knowhowConfig = require("../../../config").getConfigSync();
|
|
45
|
+
const ycmdConfig = knowhowConfig.ycmd || {};
|
|
46
|
+
const configuredPath = ycmdConfig.installPath;
|
|
47
|
+
const knowhowPath = path.join(require("os").homedir(), ".knowhow/ycmd");
|
|
48
|
+
this.ycmdPath =
|
|
49
|
+
(configuredPath && installations.find((p) => p === configuredPath)) ||
|
|
50
|
+
installations.find((p) => p === knowhowPath) ||
|
|
51
|
+
installations[0];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Start the ycmd server
|
|
56
|
+
*/
|
|
57
|
+
async start(workspaceRoot?: string, port?: number): Promise<YcmdServerInfo> {
|
|
58
|
+
return this.startWithRetry(0, workspaceRoot, port);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Start the ycmd server with retry logic for port conflicts
|
|
63
|
+
*/
|
|
64
|
+
private async startWithRetry(
|
|
65
|
+
retryCount: number,
|
|
66
|
+
workspaceRoot?: string,
|
|
67
|
+
port?: number
|
|
68
|
+
): Promise<YcmdServerInfo> {
|
|
69
|
+
const maxRetries = 5;
|
|
70
|
+
|
|
71
|
+
if (retryCount >= maxRetries) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`Failed to start ycmd server after ${maxRetries} attempts`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
return await this.doStart(workspaceRoot, port);
|
|
79
|
+
} catch (error: any) {
|
|
80
|
+
if (
|
|
81
|
+
error.message === "PORT_IN_USE" ||
|
|
82
|
+
error.message.includes("PORT_IN_USE")
|
|
83
|
+
) {
|
|
84
|
+
console.log(
|
|
85
|
+
`Retrying with incremented port (attempt ${
|
|
86
|
+
retryCount + 1
|
|
87
|
+
}/${maxRetries})`
|
|
88
|
+
);
|
|
89
|
+
const nextPort = (port || 8080) + retryCount + 1;
|
|
90
|
+
return this.startWithRetry(retryCount + 1, workspaceRoot, nextPort);
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Actually start the ycmd server (internal method)
|
|
98
|
+
*/
|
|
99
|
+
private async doStart(
|
|
100
|
+
workspaceRoot?: string,
|
|
101
|
+
port?: number
|
|
102
|
+
): Promise<YcmdServerInfo> {
|
|
103
|
+
if (this.isRunning()) {
|
|
104
|
+
throw new Error("ycmd server is already running");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log("Starting ycmd server...");
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
// Get knowhow config for ycmd settings
|
|
111
|
+
const knowhowConfig = await getConfig();
|
|
112
|
+
const ycmdConfig = knowhowConfig.ycmd || {};
|
|
113
|
+
|
|
114
|
+
// Check if ycmd is enabled in config
|
|
115
|
+
if (ycmdConfig.enabled === false) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
"ycmd is disabled in configuration. Set ycmd.enabled to true in .knowhow/knowhow.json"
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Create server configuration
|
|
122
|
+
const serverConfig = this.createServerConfig(workspaceRoot, port);
|
|
123
|
+
const availablePort = await this.findAvailablePort(serverConfig.port);
|
|
124
|
+
this.configuredPort = availablePort;
|
|
125
|
+
const configPath = await this.writeServerConfig(serverConfig);
|
|
126
|
+
|
|
127
|
+
// Start ycmd process
|
|
128
|
+
const pythonCmd = YcmdDetection.getPythonCommand();
|
|
129
|
+
const ycmdScript = path.join(this.ycmdPath, "ycmd", "__main__.py");
|
|
130
|
+
|
|
131
|
+
const args = ["--options_file", configPath];
|
|
132
|
+
args.push("--port", availablePort.toString());
|
|
133
|
+
|
|
134
|
+
this.process = spawn(pythonCmd, [ycmdScript, ...args], {
|
|
135
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
136
|
+
cwd: this.ycmdPath,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Set up process event handlers
|
|
140
|
+
try {
|
|
141
|
+
await this.setupProcessHandlers();
|
|
142
|
+
} catch (error: any) {
|
|
143
|
+
if (error.message === "PORT_IN_USE") {
|
|
144
|
+
throw error; // Re-throw to trigger retry logic
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Wait for server to start and get port
|
|
149
|
+
const serverInfo = await this.waitForServerStart();
|
|
150
|
+
|
|
151
|
+
this.serverInfo = {
|
|
152
|
+
...serverInfo,
|
|
153
|
+
pid: this.process.pid,
|
|
154
|
+
status: "running",
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
console.log(
|
|
158
|
+
`ycmd server started on ${serverInfo.host}:${serverInfo.port}`
|
|
159
|
+
);
|
|
160
|
+
return this.serverInfo;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
this.cleanup();
|
|
163
|
+
// Don't wrap PORT_IN_USE errors so retry logic works
|
|
164
|
+
if ((error as Error).message === "PORT_IN_USE") {
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
throw new Error(
|
|
168
|
+
`Failed to start ycmd server: ${(error as Error).message}`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Stop the ycmd server
|
|
175
|
+
*/
|
|
176
|
+
async stop(): Promise<void> {
|
|
177
|
+
if (!this.isRunning()) {
|
|
178
|
+
console.log("ycmd server is not running");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log("Stopping ycmd server...");
|
|
183
|
+
|
|
184
|
+
return new Promise((resolve, reject) => {
|
|
185
|
+
if (!this.process) {
|
|
186
|
+
resolve();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const timeout = setTimeout(() => {
|
|
191
|
+
// Force kill if graceful shutdown fails
|
|
192
|
+
this.process?.kill("SIGKILL");
|
|
193
|
+
reject(new Error("ycmd server failed to stop gracefully"));
|
|
194
|
+
}, 5000);
|
|
195
|
+
|
|
196
|
+
this.process.once("exit", () => {
|
|
197
|
+
clearTimeout(timeout);
|
|
198
|
+
this.cleanup();
|
|
199
|
+
console.log("ycmd server stopped");
|
|
200
|
+
resolve();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Send shutdown signal
|
|
204
|
+
this.process.kill("SIGTERM");
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Check if server is running
|
|
210
|
+
*/
|
|
211
|
+
isRunning(): boolean {
|
|
212
|
+
return (
|
|
213
|
+
this.process !== null &&
|
|
214
|
+
!this.process.killed &&
|
|
215
|
+
this.serverInfo?.status === "running"
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Get server information
|
|
221
|
+
*/
|
|
222
|
+
getServerInfo(): YcmdServerInfo | null {
|
|
223
|
+
return this.serverInfo;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Set server info for external servers (not started by this instance)
|
|
228
|
+
*/
|
|
229
|
+
setExternalServerInfo(serverInfo: YcmdServerInfo): void {
|
|
230
|
+
this.serverInfo = serverInfo;
|
|
231
|
+
// Don't set process since we didn't start it
|
|
232
|
+
this.hmacSecret = serverInfo.hmacSecret || "";
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Health check the server
|
|
237
|
+
*/
|
|
238
|
+
async healthCheck(): Promise<boolean> {
|
|
239
|
+
if (!this.isRunning() || !this.serverInfo) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
// Use YcmdClient for proper HMAC authentication
|
|
245
|
+
const client = new YcmdClient(this.serverInfo);
|
|
246
|
+
return await client.isReady();
|
|
247
|
+
} catch {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Create server configuration object
|
|
254
|
+
*/
|
|
255
|
+
private createServerConfig(workspaceRoot?: string, port?: number): any {
|
|
256
|
+
// Get knowhow config for ycmd settings
|
|
257
|
+
const knowhowConfig = require("../../../config").getConfigSync();
|
|
258
|
+
const ycmdConfig = knowhowConfig.ycmd || {};
|
|
259
|
+
|
|
260
|
+
return {
|
|
261
|
+
hmac_secret: this.hmacSecret,
|
|
262
|
+
port: port || ycmdConfig.port || 0,
|
|
263
|
+
host: "127.0.0.1",
|
|
264
|
+
server_keep_logfiles: true,
|
|
265
|
+
server_use_vim_stdout: false,
|
|
266
|
+
log_level: ycmdConfig.logLevel || "info",
|
|
267
|
+
max_diagnostics_to_display: 30,
|
|
268
|
+
auto_trigger_completion: true,
|
|
269
|
+
completion_timeout: (ycmdConfig.completionTimeout || 5000) / 1000,
|
|
270
|
+
// Language-specific settings
|
|
271
|
+
global_ycm_extra_conf: workspaceRoot
|
|
272
|
+
? path.join(workspaceRoot, ".ycm_extra_conf.py")
|
|
273
|
+
: undefined,
|
|
274
|
+
confirm_extra_conf: false,
|
|
275
|
+
auto_start_csharp_server: true,
|
|
276
|
+
auto_stop_csharp_server: true,
|
|
277
|
+
use_clangd: true,
|
|
278
|
+
clangd_binary_path: "",
|
|
279
|
+
clangd_args: [],
|
|
280
|
+
java_jdtls_workspace_root_path: workspaceRoot || "",
|
|
281
|
+
python_binary_path: YcmdDetection.getPythonCommand(),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Write server configuration to temporary file
|
|
287
|
+
*/
|
|
288
|
+
private async writeServerConfig(config: any): Promise<string> {
|
|
289
|
+
const configPath = path.join(
|
|
290
|
+
require("os").tmpdir(),
|
|
291
|
+
`ycmd_config_${Date.now()}.json`
|
|
292
|
+
);
|
|
293
|
+
await fs.promises.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
294
|
+
return configPath;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Set up process event handlers
|
|
299
|
+
*/
|
|
300
|
+
private setupProcessHandlers(): Promise<boolean> {
|
|
301
|
+
if (!this.process) {
|
|
302
|
+
return Promise.resolve(false);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return new Promise((resolve, reject) => {
|
|
306
|
+
let stdoutBuffer = "";
|
|
307
|
+
|
|
308
|
+
this.process.on("error", (error) => {
|
|
309
|
+
console.error("ycmd server process error:", error);
|
|
310
|
+
if (this.serverInfo) {
|
|
311
|
+
this.serverInfo.status = "error";
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
this.process.on("exit", (code, signal) => {
|
|
316
|
+
console.log(`ycmd server exited with code ${code}, signal ${signal}`);
|
|
317
|
+
this.cleanup();
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Capture stdout for port detection
|
|
321
|
+
this.process.stdout?.on("data", (data) => {
|
|
322
|
+
const output = data.toString();
|
|
323
|
+
stdoutBuffer += output;
|
|
324
|
+
|
|
325
|
+
// Look for server ready message with port info - try multiple patterns
|
|
326
|
+
const serverReadyMatch =
|
|
327
|
+
output.match(/serving on http:\/\/127\.0\.0\.1:(\d+)/i) ||
|
|
328
|
+
output.match(/server running at .*:(\d+)/i) ||
|
|
329
|
+
output.match(/listening on port (\d+)/i) ||
|
|
330
|
+
output.match(/port:\s*(\d+)/i);
|
|
331
|
+
|
|
332
|
+
if (serverReadyMatch) {
|
|
333
|
+
const port = parseInt(serverReadyMatch[1], 10);
|
|
334
|
+
console.log(`ycmd server detected on port ${port} from stdout`);
|
|
335
|
+
this.detectedPort = port;
|
|
336
|
+
}
|
|
337
|
+
console.log("ycmd stdout:", output);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
this.process.stderr?.on("data", (data) => {
|
|
341
|
+
const output = data.toString();
|
|
342
|
+
// console.error("ycmd stderr:", output);
|
|
343
|
+
|
|
344
|
+
// Check for "Address already in use" error
|
|
345
|
+
if (
|
|
346
|
+
output.includes("Address already in use") ||
|
|
347
|
+
output.includes("EADDRINUSE") ||
|
|
348
|
+
output.includes("bind: Address already in use")
|
|
349
|
+
) {
|
|
350
|
+
console.log(
|
|
351
|
+
`Port ${this.configuredPort} is already in use, will retry with different port`
|
|
352
|
+
);
|
|
353
|
+
reject(new Error("PORT_IN_USE"));
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
setTimeout(() => resolve(true), 1000); // Resolve after brief delay if no errors
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Wait for server to start and return server info
|
|
364
|
+
*/
|
|
365
|
+
private async waitForServerStart(): Promise<YcmdServerInfo> {
|
|
366
|
+
return new Promise((resolve, reject) => {
|
|
367
|
+
const timeout = setTimeout(() => {
|
|
368
|
+
console.log(
|
|
369
|
+
"ycmd server startup timeout - server failed to start within 30 seconds"
|
|
370
|
+
);
|
|
371
|
+
reject(new Error("ycmd server failed to start within timeout"));
|
|
372
|
+
}, 30000);
|
|
373
|
+
|
|
374
|
+
const host = "127.0.0.1";
|
|
375
|
+
// Use configured port since we pass it via --port argument
|
|
376
|
+
const getPort = () => this.configuredPort;
|
|
377
|
+
|
|
378
|
+
// Check for server readiness
|
|
379
|
+
const checkReady = async () => {
|
|
380
|
+
try {
|
|
381
|
+
const port = getPort();
|
|
382
|
+
console.log(`Checking ycmd server health on port ${port}`);
|
|
383
|
+
|
|
384
|
+
// Create a temporary server info for health check
|
|
385
|
+
const tempServerInfo: YcmdServerInfo = {
|
|
386
|
+
host,
|
|
387
|
+
port,
|
|
388
|
+
hmacSecret: this.hmacSecret,
|
|
389
|
+
status: "starting" as const,
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
const client = new YcmdClient(tempServerInfo);
|
|
393
|
+
const isReady = await client.isReady();
|
|
394
|
+
|
|
395
|
+
if (isReady) {
|
|
396
|
+
const finalPort = getPort();
|
|
397
|
+
console.log(`ycmd server is ready on port ${finalPort}`);
|
|
398
|
+
clearTimeout(timeout);
|
|
399
|
+
resolve({
|
|
400
|
+
host,
|
|
401
|
+
port: finalPort,
|
|
402
|
+
hmacSecret: this.hmacSecret,
|
|
403
|
+
status: "starting" as const,
|
|
404
|
+
});
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// If not ready yet, try again
|
|
409
|
+
setTimeout(checkReady, 1000);
|
|
410
|
+
} catch (error: any) {
|
|
411
|
+
const currentPort = getPort();
|
|
412
|
+
console.log(
|
|
413
|
+
`Health check failed for port ${currentPort}: ${error.message}`
|
|
414
|
+
);
|
|
415
|
+
// Continue trying
|
|
416
|
+
setTimeout(checkReady, 1000);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
// Start checking after a brief delay
|
|
421
|
+
setTimeout(checkReady, 2000);
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Clean up resources
|
|
427
|
+
*/
|
|
428
|
+
private cleanup(): void {
|
|
429
|
+
this.process = null;
|
|
430
|
+
if (this.serverInfo) {
|
|
431
|
+
this.serverInfo.status = "stopped";
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Force cleanup resources (for process exit handler)
|
|
437
|
+
*/
|
|
438
|
+
private forceCleanup(): void {
|
|
439
|
+
if (this.process && !this.process.killed) {
|
|
440
|
+
console.log("Force killing ycmd server process on parent exit");
|
|
441
|
+
this.process.kill("SIGKILL");
|
|
442
|
+
}
|
|
443
|
+
this.process = null;
|
|
444
|
+
this.serverInfo = null;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Setup exit handler (separate method for clarity)
|
|
449
|
+
*/
|
|
450
|
+
private setupExitHandler(): void {
|
|
451
|
+
// Handle normal process exit
|
|
452
|
+
process.on("exit", () => this.forceCleanup());
|
|
453
|
+
|
|
454
|
+
// Handle Ctrl+C (SIGINT)
|
|
455
|
+
process.on("SIGINT", () => {
|
|
456
|
+
console.log("\nReceived SIGINT (Ctrl+C), shutting down ycmd server gracefully...");
|
|
457
|
+
this.gracefulShutdown().finally(() => {
|
|
458
|
+
process.exit(0);
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
// Handle SIGTERM (termination signal)
|
|
463
|
+
process.on("SIGTERM", () => {
|
|
464
|
+
console.log("\nReceived SIGTERM, shutting down ycmd server gracefully...");
|
|
465
|
+
this.gracefulShutdown().finally(() => {
|
|
466
|
+
process.exit(0);
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Graceful shutdown method
|
|
473
|
+
*/
|
|
474
|
+
private async gracefulShutdown(): Promise<void> {
|
|
475
|
+
try {
|
|
476
|
+
await this.stop();
|
|
477
|
+
} catch (error) {
|
|
478
|
+
console.error("Error during graceful shutdown:", error);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Find an available port starting from the preferred port
|
|
484
|
+
*/
|
|
485
|
+
private async findAvailablePort(preferredPort: number): Promise<number> {
|
|
486
|
+
if (preferredPort === 0) {
|
|
487
|
+
// Start scanning from default port range
|
|
488
|
+
preferredPort = 8080;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Check if preferred port is available
|
|
492
|
+
if (await this.isPortAvailable(preferredPort)) {
|
|
493
|
+
return preferredPort;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Scan for available ports in range 8080-8090
|
|
497
|
+
for (let port = 8080; port <= 8090; port++) {
|
|
498
|
+
if (await this.isPortAvailable(port)) {
|
|
499
|
+
console.log(
|
|
500
|
+
`Port ${preferredPort} is busy, using port ${port} instead`
|
|
501
|
+
);
|
|
502
|
+
return port;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
throw new Error(`No available ports found in range 8080-8090`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Check if a port is available
|
|
511
|
+
*/
|
|
512
|
+
private async isPortAvailable(port: number): Promise<boolean> {
|
|
513
|
+
return new Promise((resolve) => {
|
|
514
|
+
const server = net.createServer();
|
|
515
|
+
server.listen(port, () => {
|
|
516
|
+
server.once("close", () => resolve(true));
|
|
517
|
+
server.close();
|
|
518
|
+
});
|
|
519
|
+
server.on("error", () => resolve(false));
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Restart the server
|
|
525
|
+
*/
|
|
526
|
+
async restart(
|
|
527
|
+
workspaceRoot?: string,
|
|
528
|
+
port?: number
|
|
529
|
+
): Promise<YcmdServerInfo> {
|
|
530
|
+
if (this.isRunning()) {
|
|
531
|
+
await this.stop();
|
|
532
|
+
}
|
|
533
|
+
return this.start(workspaceRoot, port);
|
|
534
|
+
}
|
|
535
|
+
}
|