@bniladridas/cursor 0.1.7

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.
Files changed (100) hide show
  1. package/.clang-tidy +28 -0
  2. package/.dockerignore +56 -0
  3. package/.env.example +29 -0
  4. package/.github/CODEOWNERS +2 -0
  5. package/.github/ISSUE_TEMPLATE/blank.md +27 -0
  6. package/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  8. package/.github/SECURITY.md +24 -0
  9. package/.github/codeql/codeql-config.yml +8 -0
  10. package/.github/dependabot.yml +14 -0
  11. package/.github/labeler.yml +50 -0
  12. package/.github/packaging/brand-cursor.png +0 -0
  13. package/.github/packaging/database/init.sql +48 -0
  14. package/.github/packaging/docker/Dockerfile +111 -0
  15. package/.github/packaging/docker/docker-compose.yml +56 -0
  16. package/.github/packaging/scripts/preflight.sh +413 -0
  17. package/.github/packaging/scripts/prepare-release.sh +141 -0
  18. package/.github/packaging/scripts/release.sh +22 -0
  19. package/.github/packaging/scripts/setup-git-hooks.sh +73 -0
  20. package/.github/pull_request_template.md +31 -0
  21. package/.github/signed.json +9 -0
  22. package/.github/workflows/README.md +23 -0
  23. package/.github/workflows/ci.yml +181 -0
  24. package/.github/workflows/cla.yml +33 -0
  25. package/.github/workflows/formula-sha.yml +63 -0
  26. package/.github/workflows/issue-response.yml +44 -0
  27. package/.github/workflows/labeler.yml +42 -0
  28. package/.github/workflows/pr-body.yml +49 -0
  29. package/.github/workflows/release.yml +176 -0
  30. package/.github/workflows/security.yml +94 -0
  31. package/.github/workflows/stale.yml +38 -0
  32. package/AGENTS.md +49 -0
  33. package/CHANGELOG.md +3 -0
  34. package/CMakeLists.txt +646 -0
  35. package/Formula/cursor.rb +46 -0
  36. package/LICENSE +201 -0
  37. package/Makefile +28 -0
  38. package/README.md +46 -0
  39. package/cli.js +16 -0
  40. package/include/agent.h +86 -0
  41. package/include/agent_mode.h +17 -0
  42. package/include/memory_manager.h +102 -0
  43. package/include/services/ai_service.h +31 -0
  44. package/include/services/auth_service.h +87 -0
  45. package/include/services/checkpoint_service.h +69 -0
  46. package/include/services/codebase_service.h +38 -0
  47. package/include/services/command_service.h +23 -0
  48. package/include/services/context_service.h +74 -0
  49. package/include/services/database_service.h +56 -0
  50. package/include/services/error_service.h +106 -0
  51. package/include/services/file_service.h +51 -0
  52. package/include/services/git_service.h +29 -0
  53. package/include/services/github_service.h +85 -0
  54. package/include/services/mcp_service.h +85 -0
  55. package/include/services/multi_file_service.h +93 -0
  56. package/include/services/sandbox_service.h +96 -0
  57. package/include/services/theme_service.h +67 -0
  58. package/include/services/web_service.h +52 -0
  59. package/include/utils/config.h +68 -0
  60. package/include/utils/memory_utils.h +79 -0
  61. package/include/utils/platform.h +56 -0
  62. package/include/utils/ui.h +43 -0
  63. package/include/utils/validation.h +63 -0
  64. package/include/utils/version.h.in +17 -0
  65. package/install.js +49 -0
  66. package/package.json +16 -0
  67. package/release/checksums.txt +3 -0
  68. package/release/cursor-linux/cursor_v0.1.7_linux_amd64.tar.gz +0 -0
  69. package/release/cursor-macos/cursor_v0.1.7_darwin_arm64.tar.gz +0 -0
  70. package/release/cursor-windows/cursor__windows_amd64.zip +0 -0
  71. package/src/agent.cpp +2026 -0
  72. package/src/main.cpp +97 -0
  73. package/src/memory_manager.cpp +814 -0
  74. package/src/services/ai_service.cpp +366 -0
  75. package/src/services/auth_service.cpp +779 -0
  76. package/src/services/checkpoint_service.cpp +465 -0
  77. package/src/services/codebase_service.cpp +233 -0
  78. package/src/services/command_service.cpp +82 -0
  79. package/src/services/context_service.cpp +348 -0
  80. package/src/services/database_service.cpp +148 -0
  81. package/src/services/error_service.cpp +438 -0
  82. package/src/services/file_service.cpp +349 -0
  83. package/src/services/git_service.cpp +148 -0
  84. package/src/services/github_service.cpp +435 -0
  85. package/src/services/mcp_service.cpp +481 -0
  86. package/src/services/multi_file_service.cpp +591 -0
  87. package/src/services/sandbox_service.cpp +678 -0
  88. package/src/services/theme_service.cpp +429 -0
  89. package/src/services/web_service.cpp +532 -0
  90. package/src/utils/config.cpp +77 -0
  91. package/src/utils/memory_utils.cpp +93 -0
  92. package/src/utils/ui.cpp +307 -0
  93. package/src/utils/validation.cpp +306 -0
  94. package/src/utils/version.cpp +175 -0
  95. package/tests/e2e/docker-compose.yml +195 -0
  96. package/tests/e2e/run_e2e_tests.sh +70 -0
  97. package/tests/e2e/run_tests_in_docker.sh +115 -0
  98. package/tests/main_test.cpp +16 -0
  99. package/tests/mocks/mock_ollama.py +98 -0
  100. package/tests/mocks/start_nginx.sh +64 -0
@@ -0,0 +1,481 @@
1
+ #include "services/mcp_service.h"
2
+ #include <cstdlib>
3
+ #include <filesystem>
4
+ #include <fstream>
5
+ #include <iostream>
6
+ #include <sstream>
7
+ #ifdef _WIN32
8
+ #include <process.h>
9
+ #include <windows.h>
10
+ #else
11
+ #include <signal.h>
12
+ #include <sys/wait.h>
13
+ #include <unistd.h>
14
+ #endif
15
+
16
+ namespace Services {
17
+
18
+ std::map<std::string, MCPServer> MCPService::servers;
19
+
20
+ std::string MCPService::get_mcp_config_path() {
21
+ return "data/mcp_servers.json";
22
+ }
23
+
24
+ void MCPService::ensure_mcp_directory() {
25
+ std::filesystem::create_directories("data");
26
+ }
27
+
28
+ nlohmann::json MCPService::create_mcp_request(const std::string &method,
29
+ const nlohmann::json &params) {
30
+ static int request_id = 1;
31
+ nlohmann::json request;
32
+ request["jsonrpc"] = "2.0";
33
+ request["id"] = request_id++;
34
+ request["method"] = method;
35
+ request["params"] = params;
36
+ return request;
37
+ }
38
+
39
+ nlohmann::json MCPService::send_mcp_request(const std::string &server_name,
40
+ const nlohmann::json &request) {
41
+ // For now, implement a basic JSON-RPC over stdio communication
42
+ // In a full implementation, this would handle the actual IPC with the MCP
43
+ // server
44
+
45
+ auto it = servers.find(server_name);
46
+ if (it == servers.end() || !it->second.is_running) {
47
+ nlohmann::json error_response;
48
+ error_response["error"] = "Server not found or not running";
49
+ return error_response;
50
+ }
51
+
52
+ // Simulate MCP communication - in real implementation this would:
53
+ // 1. Send JSON-RPC request to server's stdin
54
+ // 2. Read JSON-RPC response from server's stdout
55
+ // 3. Handle errors and timeouts
56
+
57
+ nlohmann::json response;
58
+ response["jsonrpc"] = "2.0";
59
+ response["id"] = request["id"];
60
+
61
+ // Mock responses for demonstration
62
+ std::string method = request["method"];
63
+ if (method == "resources/list") {
64
+ response["result"] = nlohmann::json::array();
65
+ } else if (method == "tools/list") {
66
+ response["result"] = nlohmann::json::array();
67
+ } else if (method == "prompts/list") {
68
+ response["result"] = nlohmann::json::array();
69
+ } else if (method == "ping") {
70
+ response["result"] = "pong";
71
+ } else {
72
+ response["error"] =
73
+ nlohmann::json{{"code", -32601}, {"message", "Method not found"}};
74
+ }
75
+
76
+ return response;
77
+ }
78
+
79
+ bool MCPService::start_mcp_server(const std::string &server_name) {
80
+ auto it = servers.find(server_name);
81
+ if (it == servers.end()) {
82
+ return false;
83
+ }
84
+
85
+ MCPServer &server = it->second;
86
+ if (server.is_running) {
87
+ return true; // Already running
88
+ }
89
+
90
+ try {
91
+ // In a full implementation, this would:
92
+ // 1. Fork a new process
93
+ // 2. Execute the MCP server with proper stdio redirection
94
+ // 3. Set up JSON-RPC communication channels
95
+ // 4. Handle process management
96
+
97
+ // For now, simulate server startup
98
+ server.is_running = true;
99
+ #ifdef _WIN32
100
+ server.process_id = _getpid(); // Use _getpid() on Windows
101
+ #else
102
+ server.process_id = getpid(); // Use getpid() on Unix-like systems
103
+ #endif
104
+
105
+ std::cout << "Started MCP server: " << server_name << std::endl;
106
+ return true;
107
+
108
+ } catch (const std::exception &e) {
109
+ std::cerr << "Failed to start MCP server " << server_name << ": "
110
+ << e.what() << std::endl;
111
+ return false;
112
+ }
113
+ }
114
+
115
+ bool MCPService::stop_mcp_server(const std::string &server_name) {
116
+ auto it = servers.find(server_name);
117
+ if (it == servers.end() || !it->second.is_running) {
118
+ return false;
119
+ }
120
+
121
+ MCPServer &server = it->second;
122
+
123
+ try {
124
+ // In a full implementation, this would:
125
+ // 1. Send shutdown signal to the process
126
+ // 2. Wait for graceful shutdown
127
+ // 3. Force kill if necessary
128
+ // 4. Clean up resources
129
+
130
+ server.is_running = false;
131
+ server.process_id = -1;
132
+
133
+ std::cout << "Stopped MCP server: " << server_name << std::endl;
134
+ return true;
135
+
136
+ } catch (const std::exception &e) {
137
+ std::cerr << "Failed to stop MCP server " << server_name << ": " << e.what()
138
+ << std::endl;
139
+ return false;
140
+ }
141
+ }
142
+
143
+ bool MCPService::register_mcp_server(const MCPServer &server) {
144
+ servers[server.name] = server;
145
+ save_server_config();
146
+ return true;
147
+ }
148
+
149
+ bool MCPService::unregister_mcp_server(const std::string &server_name) {
150
+ auto it = servers.find(server_name);
151
+ if (it == servers.end()) {
152
+ return false;
153
+ }
154
+
155
+ if (it->second.is_running) {
156
+ stop_mcp_server(server_name);
157
+ }
158
+
159
+ servers.erase(it);
160
+ save_server_config();
161
+ return true;
162
+ }
163
+
164
+ std::vector<std::string> MCPService::list_mcp_servers() {
165
+ std::vector<std::string> server_names;
166
+ for (const auto &pair : servers) {
167
+ server_names.push_back(pair.first);
168
+ }
169
+ return server_names;
170
+ }
171
+
172
+ MCPServer MCPService::get_mcp_server(const std::string &server_name) {
173
+ auto it = servers.find(server_name);
174
+ if (it != servers.end()) {
175
+ return it->second;
176
+ }
177
+ return MCPServer{}; // Return empty server if not found
178
+ }
179
+
180
+ bool MCPService::is_server_running(const std::string &server_name) {
181
+ auto it = servers.find(server_name);
182
+ return (it != servers.end() && it->second.is_running);
183
+ }
184
+
185
+ std::vector<MCPResource>
186
+ MCPService::list_resources(const std::string &server_name) {
187
+ std::vector<MCPResource> resources;
188
+
189
+ if (!is_server_running(server_name)) {
190
+ if (!start_mcp_server(server_name)) {
191
+ return resources;
192
+ }
193
+ }
194
+
195
+ nlohmann::json request = create_mcp_request("resources/list");
196
+ nlohmann::json response = send_mcp_request(server_name, request);
197
+
198
+ if (response.contains("result") && response["result"].is_array()) {
199
+ for (const auto &resource_json : response["result"]) {
200
+ MCPResource resource;
201
+ resource.uri = resource_json.value("uri", "");
202
+ resource.name = resource_json.value("name", "");
203
+ resource.description = resource_json.value("description", "");
204
+ resource.mime_type = resource_json.value("mimeType", "");
205
+ if (resource_json.contains("metadata")) {
206
+ resource.metadata = resource_json["metadata"];
207
+ }
208
+ resources.push_back(resource);
209
+ }
210
+ }
211
+
212
+ return resources;
213
+ }
214
+
215
+ std::string MCPService::read_resource(const std::string &server_name,
216
+ const std::string &uri) {
217
+ if (!is_server_running(server_name)) {
218
+ if (!start_mcp_server(server_name)) {
219
+ return "Error: Server not available";
220
+ }
221
+ }
222
+
223
+ nlohmann::json params;
224
+ params["uri"] = uri;
225
+
226
+ nlohmann::json request = create_mcp_request("resources/read", params);
227
+ nlohmann::json response = send_mcp_request(server_name, request);
228
+
229
+ if (response.contains("result") && response["result"].contains("contents")) {
230
+ auto contents = response["result"]["contents"];
231
+ if (contents.is_array() && !contents.empty()) {
232
+ return contents[0].value("text", "");
233
+ }
234
+ }
235
+
236
+ return "Error: Failed to read resource";
237
+ }
238
+
239
+ std::vector<MCPTool> MCPService::list_tools(const std::string &server_name) {
240
+ std::vector<MCPTool> tools;
241
+
242
+ if (!is_server_running(server_name)) {
243
+ if (!start_mcp_server(server_name)) {
244
+ return tools;
245
+ }
246
+ }
247
+
248
+ nlohmann::json request = create_mcp_request("tools/list");
249
+ nlohmann::json response = send_mcp_request(server_name, request);
250
+
251
+ if (response.contains("result") && response["result"].contains("tools") &&
252
+ response["result"]["tools"].is_array()) {
253
+ for (const auto &tool_json : response["result"]["tools"]) {
254
+ MCPTool tool;
255
+ tool.name = tool_json.value("name", "");
256
+ tool.description = tool_json.value("description", "");
257
+ if (tool_json.contains("inputSchema")) {
258
+ tool.input_schema = tool_json["inputSchema"];
259
+ }
260
+ tools.push_back(tool);
261
+ }
262
+ }
263
+
264
+ return tools;
265
+ }
266
+
267
+ nlohmann::json MCPService::call_tool(const std::string &server_name,
268
+ const std::string &tool_name,
269
+ const nlohmann::json &arguments) {
270
+ if (!is_server_running(server_name)) {
271
+ if (!start_mcp_server(server_name)) {
272
+ return nlohmann::json{{"error", "Server not available"}};
273
+ }
274
+ }
275
+
276
+ nlohmann::json params;
277
+ params["name"] = tool_name;
278
+ params["arguments"] = arguments;
279
+
280
+ nlohmann::json request = create_mcp_request("tools/call", params);
281
+ nlohmann::json response = send_mcp_request(server_name, request);
282
+
283
+ if (response.contains("result")) {
284
+ return response["result"];
285
+ }
286
+
287
+ return nlohmann::json{{"error", "Tool call failed"}};
288
+ }
289
+
290
+ std::vector<MCPPrompt>
291
+ MCPService::list_prompts(const std::string &server_name) {
292
+ std::vector<MCPPrompt> prompts;
293
+
294
+ if (!is_server_running(server_name)) {
295
+ if (!start_mcp_server(server_name)) {
296
+ return prompts;
297
+ }
298
+ }
299
+
300
+ nlohmann::json request = create_mcp_request("prompts/list");
301
+ nlohmann::json response = send_mcp_request(server_name, request);
302
+
303
+ if (response.contains("result") && response["result"].contains("prompts") &&
304
+ response["result"]["prompts"].is_array()) {
305
+ for (const auto &prompt_json : response["result"]["prompts"]) {
306
+ MCPPrompt prompt;
307
+ prompt.name = prompt_json.value("name", "");
308
+ prompt.description = prompt_json.value("description", "");
309
+ if (prompt_json.contains("arguments") &&
310
+ prompt_json["arguments"].is_array()) {
311
+ for (const auto &arg : prompt_json["arguments"]) {
312
+ if (arg.contains("name")) {
313
+ prompt.arguments.push_back(arg["name"]);
314
+ }
315
+ }
316
+ }
317
+ prompts.push_back(prompt);
318
+ }
319
+ }
320
+
321
+ return prompts;
322
+ }
323
+
324
+ std::string MCPService::get_prompt(const std::string &server_name,
325
+ const std::string &prompt_name,
326
+ const nlohmann::json &arguments) {
327
+ if (!is_server_running(server_name)) {
328
+ if (!start_mcp_server(server_name)) {
329
+ return "Error: Server not available";
330
+ }
331
+ }
332
+
333
+ nlohmann::json params;
334
+ params["name"] = prompt_name;
335
+ params["arguments"] = arguments;
336
+
337
+ nlohmann::json request = create_mcp_request("prompts/get", params);
338
+ nlohmann::json response = send_mcp_request(server_name, request);
339
+
340
+ if (response.contains("result") && response["result"].contains("messages")) {
341
+ std::string prompt_text;
342
+ for (const auto &message : response["result"]["messages"]) {
343
+ if (message.contains("content") && message["content"].contains("text")) {
344
+ prompt_text += message["content"]["text"].get<std::string>() + "\n";
345
+ }
346
+ }
347
+ return prompt_text;
348
+ }
349
+
350
+ return "Error: Failed to get prompt";
351
+ }
352
+
353
+ bool MCPService::load_server_config() {
354
+ try {
355
+ std::string config_path = get_mcp_config_path();
356
+ if (!std::filesystem::exists(config_path)) {
357
+ add_default_servers();
358
+ return true;
359
+ }
360
+
361
+ std::ifstream file(config_path);
362
+ nlohmann::json config;
363
+ file >> config;
364
+
365
+ servers.clear();
366
+
367
+ if (config.contains("servers") && config["servers"].is_object()) {
368
+ for (const auto &[name, server_json] : config["servers"].items()) {
369
+ MCPServer server;
370
+ server.name = name;
371
+ server.executable = server_json.value("executable", "");
372
+ server.working_directory = server_json.value("working_directory", ".");
373
+
374
+ if (server_json.contains("args") && server_json["args"].is_array()) {
375
+ for (const auto &arg : server_json["args"]) {
376
+ server.args.push_back(arg.get<std::string>());
377
+ }
378
+ }
379
+
380
+ if (server_json.contains("env") && server_json["env"].is_object()) {
381
+ for (const auto &[key, value] : server_json["env"].items()) {
382
+ server.env_vars[key] = value.get<std::string>();
383
+ }
384
+ }
385
+
386
+ servers[name] = server;
387
+ }
388
+ }
389
+
390
+ return true;
391
+
392
+ } catch (const std::exception &e) {
393
+ std::cerr << "Failed to load MCP server config: " << e.what() << std::endl;
394
+ add_default_servers();
395
+ return false;
396
+ }
397
+ }
398
+
399
+ bool MCPService::save_server_config() {
400
+ try {
401
+ ensure_mcp_directory();
402
+
403
+ nlohmann::json config;
404
+ config["servers"] = nlohmann::json::object();
405
+
406
+ for (const auto &[name, server] : servers) {
407
+ nlohmann::json server_json;
408
+ server_json["executable"] = server.executable;
409
+ server_json["working_directory"] = server.working_directory;
410
+ server_json["args"] = server.args;
411
+ server_json["env"] = server.env_vars;
412
+
413
+ config["servers"][name] = server_json;
414
+ }
415
+
416
+ std::ofstream file(get_mcp_config_path());
417
+ file << config.dump(2);
418
+
419
+ return true;
420
+
421
+ } catch (const std::exception &e) {
422
+ std::cerr << "Failed to save MCP server config: " << e.what() << std::endl;
423
+ return false;
424
+ }
425
+ }
426
+
427
+ void MCPService::add_default_servers() {
428
+ // Add some example MCP servers
429
+ MCPServer filesystem_server;
430
+ filesystem_server.name = "filesystem";
431
+ filesystem_server.executable = "npx";
432
+ filesystem_server.args = {"@modelcontextprotocol/server-filesystem", "."};
433
+ filesystem_server.working_directory = ".";
434
+ servers["filesystem"] = filesystem_server;
435
+
436
+ MCPServer git_server;
437
+ git_server.name = "git";
438
+ git_server.executable = "npx";
439
+ git_server.args = {"@modelcontextprotocol/server-git", "."};
440
+ git_server.working_directory = ".";
441
+ servers["git"] = git_server;
442
+
443
+ save_server_config();
444
+ }
445
+
446
+ bool MCPService::ping_server(const std::string &server_name) {
447
+ if (!is_server_running(server_name)) {
448
+ return false;
449
+ }
450
+
451
+ nlohmann::json request = create_mcp_request("ping");
452
+ nlohmann::json response = send_mcp_request(server_name, request);
453
+
454
+ return response.contains("result") && response["result"] == "pong";
455
+ }
456
+
457
+ std::string MCPService::get_server_status(const std::string &server_name) {
458
+ auto it = servers.find(server_name);
459
+ if (it == servers.end()) {
460
+ return "Not registered";
461
+ }
462
+
463
+ if (!it->second.is_running) {
464
+ return "Stopped";
465
+ }
466
+
467
+ if (ping_server(server_name)) {
468
+ return "Running";
469
+ }
470
+ return "Unresponsive";
471
+ }
472
+
473
+ void MCPService::cleanup_dead_servers() {
474
+ for (auto &[name, server] : servers) {
475
+ if (server.is_running && !ping_server(name)) {
476
+ server.is_running = false;
477
+ server.process_id = -1;
478
+ }
479
+ }
480
+ }
481
+ } // namespace Services