mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 09:17:53 +00:00
remove pid from lockfile name of ide connection file
This commit is contained in:
48
package-lock.json
generated
48
package-lock.json
generated
@@ -568,7 +568,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
@@ -592,7 +591,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
@@ -2157,7 +2155,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
|
||||||
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
|
"integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
}
|
}
|
||||||
@@ -3671,7 +3668,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
|
||||||
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.10.4",
|
"@babel/code-frame": "^7.10.4",
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
@@ -4142,7 +4138,6 @@
|
|||||||
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
|
"integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
@@ -4153,7 +4148,6 @@
|
|||||||
"integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==",
|
"integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/react": "^19.0.0"
|
"@types/react": "^19.0.0"
|
||||||
}
|
}
|
||||||
@@ -4359,7 +4353,6 @@
|
|||||||
"integrity": "sha512-6sMvZePQrnZH2/cJkwRpkT7DxoAWh+g6+GFRK6bV3YQo7ogi3SX5rgF6099r5Q53Ma5qeT7LGmOmuIutF4t3lA==",
|
"integrity": "sha512-6sMvZePQrnZH2/cJkwRpkT7DxoAWh+g6+GFRK6bV3YQo7ogi3SX5rgF6099r5Q53Ma5qeT7LGmOmuIutF4t3lA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.35.0",
|
"@typescript-eslint/scope-manager": "8.35.0",
|
||||||
"@typescript-eslint/types": "8.35.0",
|
"@typescript-eslint/types": "8.35.0",
|
||||||
@@ -5135,7 +5128,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -5530,7 +5522,8 @@
|
|||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/array-includes": {
|
"node_modules/array-includes": {
|
||||||
"version": "3.1.9",
|
"version": "3.1.9",
|
||||||
@@ -6865,6 +6858,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safe-buffer": "5.2.1"
|
"safe-buffer": "5.2.1"
|
||||||
},
|
},
|
||||||
@@ -7982,7 +7976,6 @@
|
|||||||
"integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==",
|
"integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
@@ -8518,6 +8511,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
"array-flatten": "1.1.1",
|
"array-flatten": "1.1.1",
|
||||||
@@ -8579,6 +8573,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||||
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@@ -8588,6 +8583,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
@@ -8597,6 +8593,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
@@ -8763,6 +8760,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||||
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "2.6.9",
|
"debug": "2.6.9",
|
||||||
"encodeurl": "~2.0.0",
|
"encodeurl": "~2.0.0",
|
||||||
@@ -8781,6 +8779,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
@@ -8789,13 +8788,15 @@
|
|||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/finalhandler/node_modules/statuses": {
|
"node_modules/finalhandler/node_modules/statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
@@ -9909,7 +9910,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ink/-/ink-6.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/ink/-/ink-6.2.3.tgz",
|
||||||
"integrity": "sha512-fQkfEJjKbLXIcVWEE3MvpYSnwtbbmRsmeNDNz1pIuOFlwE+UF2gsy228J36OXKZGWJWZJKUigphBSqCNMcARtg==",
|
"integrity": "sha512-fQkfEJjKbLXIcVWEE3MvpYSnwtbbmRsmeNDNz1pIuOFlwE+UF2gsy228J36OXKZGWJWZJKUigphBSqCNMcARtg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alcalzone/ansi-tokenize": "^0.2.0",
|
"@alcalzone/ansi-tokenize": "^0.2.0",
|
||||||
"ansi-escapes": "^7.0.0",
|
"ansi-escapes": "^7.0.0",
|
||||||
@@ -11864,6 +11864,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
@@ -13162,7 +13163,8 @@
|
|||||||
"version": "0.1.12",
|
"version": "0.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/path-type": {
|
"node_modules/path-type": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@@ -13821,7 +13823,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
|
||||||
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
|
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -13832,7 +13833,6 @@
|
|||||||
"integrity": "sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==",
|
"integrity": "sha512-cq/o30z9W2Wb4rzBefjv5fBalHU0rJGZCHAkf/RHSBWSSYwh8PlQTqqOJmgIIbBtpj27T6FIPXeomIjZtCNVqA==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"shell-quote": "^1.6.1",
|
"shell-quote": "^1.6.1",
|
||||||
"ws": "^7"
|
"ws": "^7"
|
||||||
@@ -13866,7 +13866,6 @@
|
|||||||
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
|
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scheduler": "^0.26.0"
|
"scheduler": "^0.26.0"
|
||||||
},
|
},
|
||||||
@@ -15932,7 +15931,6 @@
|
|||||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -16112,8 +16110,7 @@
|
|||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
"license": "0BSD",
|
"license": "0BSD"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/tsx": {
|
"node_modules/tsx": {
|
||||||
"version": "4.20.3",
|
"version": "4.20.3",
|
||||||
@@ -16121,7 +16118,6 @@
|
|||||||
"integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==",
|
"integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "~0.25.0",
|
"esbuild": "~0.25.0",
|
||||||
"get-tsconfig": "^4.7.5"
|
"get-tsconfig": "^4.7.5"
|
||||||
@@ -16316,7 +16312,6 @@
|
|||||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -16624,6 +16619,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4.0"
|
"node": ">= 0.4.0"
|
||||||
}
|
}
|
||||||
@@ -16679,7 +16675,6 @@
|
|||||||
"integrity": "sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==",
|
"integrity": "sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"fdir": "^6.4.6",
|
"fdir": "^6.4.6",
|
||||||
@@ -16793,7 +16788,6 @@
|
|||||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -16807,7 +16801,6 @@
|
|||||||
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
|
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/chai": "^5.2.2",
|
"@types/chai": "^5.2.2",
|
||||||
"@vitest/expect": "3.2.4",
|
"@vitest/expect": "3.2.4",
|
||||||
@@ -17486,7 +17479,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
|
||||||
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
@@ -17757,7 +17749,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -17776,10 +17767,11 @@
|
|||||||
},
|
},
|
||||||
"packages/sdk-typescript": {
|
"packages/sdk-typescript": {
|
||||||
"name": "@qwen-code/sdk",
|
"name": "@qwen-code/sdk",
|
||||||
"version": "0.5.1",
|
"version": "0.1.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@modelcontextprotocol/sdk": "^1.0.4"
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
||||||
|
"tiktoken": "^1.0.21"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.14.0",
|
"@types/node": "^20.14.0",
|
||||||
|
|||||||
@@ -102,17 +102,12 @@ describe('IdeClient', () => {
|
|||||||
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '8080';
|
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '8080';
|
||||||
const config = { port: '8080' };
|
const config = { port: '8080' };
|
||||||
vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
|
vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValue([]);
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
const ideClient = await IdeClient.getInstance();
|
||||||
await ideClient.connect();
|
await ideClient.connect();
|
||||||
|
|
||||||
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
||||||
path.join('/home/test', '.qwen', 'ide', '12345-8080.lock'),
|
path.join('/home/test', '.qwen', 'ide', '8080.lock'),
|
||||||
'utf8',
|
'utf8',
|
||||||
);
|
);
|
||||||
expect(StreamableHTTPClientTransport).toHaveBeenCalledWith(
|
expect(StreamableHTTPClientTransport).toHaveBeenCalledWith(
|
||||||
@@ -127,13 +122,9 @@ describe('IdeClient', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should connect using stdio when stdio config is provided in file', async () => {
|
it('should connect using stdio when stdio config is provided in file', async () => {
|
||||||
|
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '8080';
|
||||||
const config = { stdio: { command: 'test-cmd', args: ['--foo'] } };
|
const config = { stdio: { command: 'test-cmd', args: ['--foo'] } };
|
||||||
vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
|
vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValue([]);
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
const ideClient = await IdeClient.getInstance();
|
||||||
await ideClient.connect();
|
await ideClient.connect();
|
||||||
@@ -146,19 +137,16 @@ describe('IdeClient', () => {
|
|||||||
expect(ideClient.getConnectionStatus().status).toBe(
|
expect(ideClient.getConnectionStatus().status).toBe(
|
||||||
IDEConnectionStatus.Connected,
|
IDEConnectionStatus.Connected,
|
||||||
);
|
);
|
||||||
|
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should prioritize port over stdio when both are in config file', async () => {
|
it('should prioritize port over stdio when both are in config file', async () => {
|
||||||
|
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '8080';
|
||||||
const config = {
|
const config = {
|
||||||
port: '8080',
|
port: '8080',
|
||||||
stdio: { command: 'test-cmd', args: ['--foo'] },
|
stdio: { command: 'test-cmd', args: ['--foo'] },
|
||||||
};
|
};
|
||||||
vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
|
vi.mocked(fs.promises.readFile).mockResolvedValue(JSON.stringify(config));
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValue([]);
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
const ideClient = await IdeClient.getInstance();
|
||||||
await ideClient.connect();
|
await ideClient.connect();
|
||||||
@@ -168,6 +156,7 @@ describe('IdeClient', () => {
|
|||||||
expect(ideClient.getConnectionStatus().status).toBe(
|
expect(ideClient.getConnectionStatus().status).toBe(
|
||||||
IDEConnectionStatus.Connected,
|
IDEConnectionStatus.Connected,
|
||||||
);
|
);
|
||||||
|
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should connect using HTTP when port is provided in environment variables', async () => {
|
it('should connect using HTTP when port is provided in environment variables', async () => {
|
||||||
@@ -282,7 +271,7 @@ describe('IdeClient', () => {
|
|||||||
|
|
||||||
expect(result).toEqual(config);
|
expect(result).toEqual(config);
|
||||||
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
||||||
path.join('/home/test', '.qwen', 'ide', '12345-1234.lock'),
|
path.join('/home/test', '.qwen', 'ide', '1234.lock'),
|
||||||
'utf8',
|
'utf8',
|
||||||
);
|
);
|
||||||
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
||||||
@@ -290,11 +279,6 @@ describe('IdeClient', () => {
|
|||||||
|
|
||||||
it('should return undefined if no config files are found', async () => {
|
it('should return undefined if no config files are found', async () => {
|
||||||
vi.mocked(fs.promises.readFile).mockRejectedValue(new Error('not found'));
|
vi.mocked(fs.promises.readFile).mockRejectedValue(new Error('not found'));
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValue([]);
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
const ideClient = await IdeClient.getInstance();
|
||||||
const result = await (
|
const result = await (
|
||||||
@@ -306,26 +290,15 @@ describe('IdeClient', () => {
|
|||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find and parse a single lock file matching the IDE pid', async () => {
|
it('should read legacy pid config when available', async () => {
|
||||||
const config = {
|
const config = {
|
||||||
port: '5678',
|
port: '5678',
|
||||||
workspacePath: '/test/workspace',
|
workspacePath: '/test/workspace',
|
||||||
ppid: 12345,
|
ppid: 12345,
|
||||||
};
|
};
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValueOnce(['12345-5678.lock']);
|
|
||||||
vi.mocked(fs.promises.stat).mockResolvedValueOnce({
|
|
||||||
mtimeMs: 123,
|
|
||||||
} as unknown as fs.Stats);
|
|
||||||
vi.mocked(fs.promises.readFile).mockResolvedValueOnce(
|
vi.mocked(fs.promises.readFile).mockResolvedValueOnce(
|
||||||
JSON.stringify(config),
|
JSON.stringify(config),
|
||||||
);
|
);
|
||||||
vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
|
|
||||||
isValid: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
const ideClient = await IdeClient.getInstance();
|
||||||
const result = await (
|
const result = await (
|
||||||
@@ -336,106 +309,18 @@ describe('IdeClient', () => {
|
|||||||
|
|
||||||
expect(result).toEqual(config);
|
expect(result).toEqual(config);
|
||||||
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
||||||
path.join('/home/test', '.qwen', 'ide', '12345-5678.lock'),
|
path.join('/tmp', 'qwen-code-ide-server-12345.json'),
|
||||||
'utf8',
|
'utf8',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should filter out configs with invalid workspace paths', async () => {
|
it('should fall back to legacy port file when pid file is missing', async () => {
|
||||||
const validConfig = {
|
|
||||||
port: '5678',
|
|
||||||
workspacePath: '/test/workspace',
|
|
||||||
};
|
|
||||||
const invalidConfig = {
|
|
||||||
port: '1111',
|
|
||||||
workspacePath: '/invalid/workspace',
|
|
||||||
};
|
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValueOnce(['12345-1111.lock', '12345-5678.lock']); // ~/.qwen/ide scan
|
|
||||||
vi.mocked(fs.promises.stat)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 1 } as unknown as fs.Stats)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 2 } as unknown as fs.Stats);
|
|
||||||
vi.mocked(fs.promises.readFile)
|
|
||||||
.mockResolvedValueOnce(JSON.stringify(invalidConfig))
|
|
||||||
.mockResolvedValueOnce(JSON.stringify(validConfig));
|
|
||||||
|
|
||||||
const validateSpy = vi
|
|
||||||
.spyOn(IdeClient, 'validateWorkspacePath')
|
|
||||||
.mockImplementation((ideWorkspacePath) => ({
|
|
||||||
isValid: ideWorkspacePath === '/test/workspace',
|
|
||||||
}));
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
|
||||||
const result = await (
|
|
||||||
ideClient as unknown as {
|
|
||||||
getConnectionConfigFromFile: () => Promise<unknown>;
|
|
||||||
}
|
|
||||||
).getConnectionConfigFromFile();
|
|
||||||
|
|
||||||
expect(result).toEqual(validConfig);
|
|
||||||
expect(validateSpy).toHaveBeenCalledWith(
|
|
||||||
'/invalid/workspace',
|
|
||||||
'/test/workspace/sub-dir',
|
|
||||||
);
|
|
||||||
expect(validateSpy).toHaveBeenCalledWith(
|
|
||||||
'/test/workspace',
|
|
||||||
'/test/workspace/sub-dir',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the first valid config when multiple workspaces are valid', async () => {
|
|
||||||
const config1 = { port: '1111', workspacePath: '/test/workspace' };
|
|
||||||
const config2 = { port: '2222', workspacePath: '/test/workspace2' };
|
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValueOnce(['12345-1111.lock', '12345-2222.lock']); // ~/.qwen/ide scan
|
|
||||||
// Make config1 "newer" so it wins when both are valid.
|
|
||||||
vi.mocked(fs.promises.stat)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 2 } as unknown as fs.Stats)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 1 } as unknown as fs.Stats);
|
|
||||||
vi.mocked(fs.promises.readFile)
|
|
||||||
.mockResolvedValueOnce(JSON.stringify(config1))
|
|
||||||
.mockResolvedValueOnce(JSON.stringify(config2));
|
|
||||||
vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
|
|
||||||
isValid: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
|
||||||
const result = await (
|
|
||||||
ideClient as unknown as {
|
|
||||||
getConnectionConfigFromFile: () => Promise<unknown>;
|
|
||||||
}
|
|
||||||
).getConnectionConfigFromFile();
|
|
||||||
|
|
||||||
expect(result).toEqual(config1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should prioritize the config matching the port from the environment variable', async () => {
|
|
||||||
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '2222';
|
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '2222';
|
||||||
const config1 = { port: '1111', workspacePath: '/test/workspace' };
|
|
||||||
const config2 = { port: '2222', workspacePath: '/test/workspace2' };
|
const config2 = { port: '2222', workspacePath: '/test/workspace2' };
|
||||||
vi.mocked(fs.promises.readFile).mockRejectedValueOnce(
|
|
||||||
new Error('not found'),
|
|
||||||
); // For ~/.qwen/ide/<pid>-<port>.lock
|
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValueOnce(['12345-1111.lock', '12345-2222.lock']); // ~/.qwen/ide scan
|
|
||||||
vi.mocked(fs.promises.stat)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 1 } as unknown as fs.Stats)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 2 } as unknown as fs.Stats);
|
|
||||||
vi.mocked(fs.promises.readFile)
|
vi.mocked(fs.promises.readFile)
|
||||||
.mockResolvedValueOnce(JSON.stringify(config1))
|
.mockRejectedValueOnce(new Error('not found')) // ~/.qwen/ide/<port>.lock
|
||||||
|
.mockRejectedValueOnce(new Error('not found')) // legacy pid file
|
||||||
.mockResolvedValueOnce(JSON.stringify(config2));
|
.mockResolvedValueOnce(JSON.stringify(config2));
|
||||||
vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
|
|
||||||
isValid: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
const ideClient = await IdeClient.getInstance();
|
||||||
const result = await (
|
const result = await (
|
||||||
@@ -445,25 +330,23 @@ describe('IdeClient', () => {
|
|||||||
).getConnectionConfigFromFile();
|
).getConnectionConfigFromFile();
|
||||||
|
|
||||||
expect(result).toEqual(config2);
|
expect(result).toEqual(config2);
|
||||||
|
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
||||||
|
path.join('/tmp', 'qwen-code-ide-server-12345.json'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
||||||
|
path.join('/tmp', 'qwen-code-ide-server-2222.json'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle invalid JSON in one of the config files', async () => {
|
it('should fall back to legacy config when env lock file has invalid JSON', async () => {
|
||||||
const validConfig = { port: '2222', workspacePath: '/test/workspace' };
|
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '3333';
|
||||||
(
|
const config = { port: '1111', workspacePath: '/test/workspace' };
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValueOnce(['12345-1111.lock', '12345-2222.lock']); // ~/.qwen/ide scan
|
|
||||||
vi.mocked(fs.promises.stat)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 2 } as unknown as fs.Stats)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 1 } as unknown as fs.Stats);
|
|
||||||
vi.mocked(fs.promises.readFile)
|
vi.mocked(fs.promises.readFile)
|
||||||
.mockResolvedValueOnce('invalid json')
|
.mockResolvedValueOnce('invalid json')
|
||||||
.mockResolvedValueOnce(JSON.stringify(validConfig));
|
.mockResolvedValueOnce(JSON.stringify(config));
|
||||||
vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
|
|
||||||
isValid: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
const ideClient = await IdeClient.getInstance();
|
||||||
const result = await (
|
const result = await (
|
||||||
@@ -472,99 +355,7 @@ describe('IdeClient', () => {
|
|||||||
}
|
}
|
||||||
).getConnectionConfigFromFile();
|
).getConnectionConfigFromFile();
|
||||||
|
|
||||||
expect(result).toEqual(validConfig);
|
expect(result).toEqual(config);
|
||||||
});
|
|
||||||
|
|
||||||
it('should return undefined if readdir throws an error', async () => {
|
|
||||||
vi.mocked(fs.promises.readFile).mockRejectedValueOnce(
|
|
||||||
new Error('not found'),
|
|
||||||
);
|
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockRejectedValueOnce(new Error('readdir failed')); // ~/.qwen/ide scan
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
|
||||||
const result = await (
|
|
||||||
ideClient as unknown as {
|
|
||||||
getConnectionConfigFromFile: () => Promise<unknown>;
|
|
||||||
}
|
|
||||||
).getConnectionConfigFromFile();
|
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should ignore files with invalid names', async () => {
|
|
||||||
const validConfig = { port: '3333', workspacePath: '/test/workspace' };
|
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValueOnce([
|
|
||||||
'12345-3333.lock', // valid
|
|
||||||
'not-a-config-file.txt', // invalid
|
|
||||||
'asdf.lock', // invalid
|
|
||||||
'12345-asdf.lock', // invalid
|
|
||||||
]); // ~/.qwen/ide scan
|
|
||||||
vi.mocked(fs.promises.stat).mockResolvedValueOnce({
|
|
||||||
mtimeMs: 123,
|
|
||||||
} as unknown as fs.Stats);
|
|
||||||
vi.mocked(fs.promises.readFile).mockResolvedValueOnce(
|
|
||||||
JSON.stringify(validConfig),
|
|
||||||
);
|
|
||||||
vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
|
|
||||||
isValid: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
|
||||||
const result = await (
|
|
||||||
ideClient as unknown as {
|
|
||||||
getConnectionConfigFromFile: () => Promise<unknown>;
|
|
||||||
}
|
|
||||||
).getConnectionConfigFromFile();
|
|
||||||
|
|
||||||
expect(result).toEqual(validConfig);
|
|
||||||
expect(fs.promises.readFile).toHaveBeenCalledWith(
|
|
||||||
path.join('/home/test', '.qwen', 'ide', '12345-3333.lock'),
|
|
||||||
'utf8',
|
|
||||||
);
|
|
||||||
expect(fs.promises.readFile).not.toHaveBeenCalledWith(
|
|
||||||
path.join('/home/test', '.qwen', 'ide', 'not-a-config-file.txt'),
|
|
||||||
'utf8',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should match env port string to a number port in the config', async () => {
|
|
||||||
process.env['QWEN_CODE_IDE_SERVER_PORT'] = '3333';
|
|
||||||
const config1 = { port: 1111, workspacePath: '/test/workspace' };
|
|
||||||
const config2 = { port: 3333, workspacePath: '/test/workspace2' };
|
|
||||||
vi.mocked(fs.promises.readFile).mockRejectedValueOnce(
|
|
||||||
new Error('not found'),
|
|
||||||
);
|
|
||||||
(
|
|
||||||
vi.mocked(fs.promises.readdir) as Mock<
|
|
||||||
(path: fs.PathLike) => Promise<string[]>
|
|
||||||
>
|
|
||||||
).mockResolvedValueOnce(['12345-1111.lock', '12345-3333.lock']); // ~/.qwen/ide scan
|
|
||||||
vi.mocked(fs.promises.stat)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 1 } as unknown as fs.Stats)
|
|
||||||
.mockResolvedValueOnce({ mtimeMs: 2 } as unknown as fs.Stats);
|
|
||||||
vi.mocked(fs.promises.readFile)
|
|
||||||
.mockResolvedValueOnce(JSON.stringify(config1))
|
|
||||||
.mockResolvedValueOnce(JSON.stringify(config2));
|
|
||||||
vi.spyOn(IdeClient, 'validateWorkspacePath').mockReturnValue({
|
|
||||||
isValid: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const ideClient = await IdeClient.getInstance();
|
|
||||||
const result = await (
|
|
||||||
ideClient as unknown as {
|
|
||||||
getConnectionConfigFromFile: () => Promise<unknown>;
|
|
||||||
}
|
|
||||||
).getConnectionConfigFromFile();
|
|
||||||
|
|
||||||
expect(result).toEqual(config2);
|
|
||||||
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
delete process.env['QWEN_CODE_IDE_SERVER_PORT'];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -573,32 +573,76 @@ export class IdeClient {
|
|||||||
| (ConnectionConfig & { workspacePath?: string; ideInfo?: IdeInfo })
|
| (ConnectionConfig & { workspacePath?: string; ideInfo?: IdeInfo })
|
||||||
| undefined
|
| undefined
|
||||||
> {
|
> {
|
||||||
if (!this.ideProcessInfo) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preferred: lock file(s) in global qwen dir (~/.qwen/ide/<pid>-<port>.lock)
|
|
||||||
// 1) If QWEN_CODE_IDE_SERVER_PORT is set, prefer ~/.qwen/ide/<pid>-<port>.lock
|
|
||||||
// 2) Otherwise (or on failure), scan ~/.qwen/ide for <pid>-*.lock and select:
|
|
||||||
// - valid workspace path (validateWorkspacePath)
|
|
||||||
const ideDir = Storage.getGlobalIdeDir();
|
|
||||||
const idePid = this.ideProcessInfo.pid;
|
|
||||||
const portFromEnv = this.getPortFromEnv();
|
const portFromEnv = this.getPortFromEnv();
|
||||||
if (portFromEnv) {
|
if (portFromEnv) {
|
||||||
try {
|
try {
|
||||||
const lockFile = path.join(ideDir, `${idePid}-${portFromEnv}.lock`);
|
const ideDir = Storage.getGlobalIdeDir();
|
||||||
|
const lockFile = path.join(ideDir, `${portFromEnv}.lock`);
|
||||||
const lockFileContents = await fs.promises.readFile(lockFile, 'utf8');
|
const lockFileContents = await fs.promises.readFile(lockFile, 'utf8');
|
||||||
return JSON.parse(lockFileContents);
|
return JSON.parse(lockFileContents);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
// Fall through to scanning / legacy discovery.
|
// Fall through to legacy discovery.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Legacy discovery for VSCode extension < v0.5.1.
|
||||||
|
return this.getLegacyConnectionConfig(portFromEnv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy connection files were written in the global temp directory.
|
||||||
|
private async getLegacyConnectionConfig(
|
||||||
|
portFromEnv?: string,
|
||||||
|
): Promise<
|
||||||
|
| (ConnectionConfig & { workspacePath?: string; ideInfo?: IdeInfo })
|
||||||
|
| undefined
|
||||||
|
> {
|
||||||
|
if (this.ideProcessInfo) {
|
||||||
try {
|
try {
|
||||||
const fileRegex = new RegExp(`^${idePid}-\\d+\\.lock$`);
|
const portFile = path.join(
|
||||||
const lockFiles = (await fs.promises.readdir(ideDir)).filter((file) =>
|
os.tmpdir(),
|
||||||
|
`qwen-code-ide-server-${this.ideProcessInfo.pid}.json`,
|
||||||
|
);
|
||||||
|
const portFileContents = await fs.promises.readFile(portFile, 'utf8');
|
||||||
|
return JSON.parse(portFileContents);
|
||||||
|
} catch (_) {
|
||||||
|
// For older/newer extension versions, the file name matches the pattern
|
||||||
|
// /^qwen-code-ide-server-${pid}-\d+\.json$/. If multiple IDE
|
||||||
|
// windows are open, multiple files matching the pattern are expected to
|
||||||
|
// exist.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (portFromEnv) {
|
||||||
|
try {
|
||||||
|
const portFile = path.join(
|
||||||
|
os.tmpdir(),
|
||||||
|
`qwen-code-ide-server-${portFromEnv}.json`,
|
||||||
|
);
|
||||||
|
const portFileContents = await fs.promises.readFile(portFile, 'utf8');
|
||||||
|
return JSON.parse(portFileContents);
|
||||||
|
} catch (_) {
|
||||||
|
// Ignore and fall through.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async getAllConnectionConfigs(
|
||||||
|
ideDir: string,
|
||||||
|
): Promise<
|
||||||
|
ConnectionConfig & Array<{ workspacePath?: string; ideInfo?: IdeInfo }>
|
||||||
|
> {
|
||||||
|
const fileRegex = new RegExp('^\\d+\\.lock$');
|
||||||
|
let lockFiles: string[];
|
||||||
|
try {
|
||||||
|
lockFiles = (await fs.promises.readdir(ideDir)).filter((file) =>
|
||||||
fileRegex.test(file),
|
fileRegex.test(file),
|
||||||
);
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logger.debug('Failed to read IDE connection directory:', e);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const fileContents = await Promise.all(
|
const fileContents = await Promise.all(
|
||||||
lockFiles.map(async (file) => {
|
lockFiles.map(async (file) => {
|
||||||
@@ -621,56 +665,11 @@ export class IdeClient {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const validWorkspaces = fileContents
|
|
||||||
|
return fileContents
|
||||||
.filter(({ parsed }) => parsed !== undefined)
|
.filter(({ parsed }) => parsed !== undefined)
|
||||||
.sort((a, b) => b.mtimeMs - a.mtimeMs)
|
.sort((a, b) => b.mtimeMs - a.mtimeMs)
|
||||||
.map(({ parsed }) => parsed)
|
.map(({ parsed }) => parsed);
|
||||||
.filter((content) => {
|
|
||||||
const { isValid } = IdeClient.validateWorkspacePath(
|
|
||||||
content.workspacePath,
|
|
||||||
process.cwd(),
|
|
||||||
);
|
|
||||||
return isValid;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (validWorkspaces.length > 0) {
|
|
||||||
if (validWorkspaces.length === 1) {
|
|
||||||
return validWorkspaces[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validWorkspaces.length > 1 && portFromEnv) {
|
|
||||||
const matchingPort = validWorkspaces.find(
|
|
||||||
(content) => String(content.port) === portFromEnv,
|
|
||||||
);
|
|
||||||
if (matchingPort) {
|
|
||||||
return matchingPort;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validWorkspaces.length > 1) {
|
|
||||||
return validWorkspaces[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
// Fall through to legacy discovery mechanisms.
|
|
||||||
}
|
|
||||||
|
|
||||||
// For backwards compatability: single file in system temp dir named by PID.
|
|
||||||
try {
|
|
||||||
const portFile = path.join(
|
|
||||||
os.tmpdir(),
|
|
||||||
`qwen-code-ide-server-${this.ideProcessInfo.pid}.json`,
|
|
||||||
);
|
|
||||||
const portFileContents = await fs.promises.readFile(portFile, 'utf8');
|
|
||||||
return JSON.parse(portFileContents);
|
|
||||||
} catch (_) {
|
|
||||||
// For older/newer extension versions, the file name matches the pattern
|
|
||||||
// /^qwen-code-ide-server-${pid}-\d+\.json$/. If multiple IDE
|
|
||||||
// windows are open, multiple files matching the pattern are expected to
|
|
||||||
// exist.
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private createProxyAwareFetch() {
|
private createProxyAwareFetch() {
|
||||||
|
|||||||
@@ -133,13 +133,14 @@ describe('IDEServer', () => {
|
|||||||
'/home/test',
|
'/home/test',
|
||||||
'.qwen',
|
'.qwen',
|
||||||
'ide',
|
'ide',
|
||||||
`${process.ppid}-${port}.lock`,
|
`${port}.lock`,
|
||||||
);
|
);
|
||||||
const expectedContent = JSON.stringify({
|
const expectedContent = JSON.stringify({
|
||||||
port: parseInt(port, 10),
|
port: parseInt(port, 10),
|
||||||
workspacePath: expectedWorkspacePaths,
|
workspacePath: expectedWorkspacePaths,
|
||||||
ppid: process.ppid,
|
ppid: process.ppid,
|
||||||
authToken: 'test-auth-token',
|
authToken: 'test-auth-token',
|
||||||
|
ideName: 'VS Code',
|
||||||
});
|
});
|
||||||
expect(fs.writeFile).toHaveBeenCalledWith(
|
expect(fs.writeFile).toHaveBeenCalledWith(
|
||||||
expectedLockFile,
|
expectedLockFile,
|
||||||
@@ -164,13 +165,14 @@ describe('IDEServer', () => {
|
|||||||
'/home/test',
|
'/home/test',
|
||||||
'.qwen',
|
'.qwen',
|
||||||
'ide',
|
'ide',
|
||||||
`${process.ppid}-${port}.lock`,
|
`${port}.lock`,
|
||||||
);
|
);
|
||||||
const expectedContent = JSON.stringify({
|
const expectedContent = JSON.stringify({
|
||||||
port: parseInt(port, 10),
|
port: parseInt(port, 10),
|
||||||
workspacePath: '/foo/bar',
|
workspacePath: '/foo/bar',
|
||||||
ppid: process.ppid,
|
ppid: process.ppid,
|
||||||
authToken: 'test-auth-token',
|
authToken: 'test-auth-token',
|
||||||
|
ideName: 'VS Code',
|
||||||
});
|
});
|
||||||
expect(fs.writeFile).toHaveBeenCalledWith(
|
expect(fs.writeFile).toHaveBeenCalledWith(
|
||||||
expectedLockFile,
|
expectedLockFile,
|
||||||
@@ -195,13 +197,14 @@ describe('IDEServer', () => {
|
|||||||
'/home/test',
|
'/home/test',
|
||||||
'.qwen',
|
'.qwen',
|
||||||
'ide',
|
'ide',
|
||||||
`${process.ppid}-${port}.lock`,
|
`${port}.lock`,
|
||||||
);
|
);
|
||||||
const expectedContent = JSON.stringify({
|
const expectedContent = JSON.stringify({
|
||||||
port: parseInt(port, 10),
|
port: parseInt(port, 10),
|
||||||
workspacePath: '',
|
workspacePath: '',
|
||||||
ppid: process.ppid,
|
ppid: process.ppid,
|
||||||
authToken: 'test-auth-token',
|
authToken: 'test-auth-token',
|
||||||
|
ideName: 'VS Code',
|
||||||
});
|
});
|
||||||
expect(fs.writeFile).toHaveBeenCalledWith(
|
expect(fs.writeFile).toHaveBeenCalledWith(
|
||||||
expectedLockFile,
|
expectedLockFile,
|
||||||
@@ -240,13 +243,14 @@ describe('IDEServer', () => {
|
|||||||
'/home/test',
|
'/home/test',
|
||||||
'.qwen',
|
'.qwen',
|
||||||
'ide',
|
'ide',
|
||||||
`${process.ppid}-${port}.lock`,
|
`${port}.lock`,
|
||||||
);
|
);
|
||||||
const expectedContent = JSON.stringify({
|
const expectedContent = JSON.stringify({
|
||||||
port: parseInt(port, 10),
|
port: parseInt(port, 10),
|
||||||
workspacePath: expectedWorkspacePaths,
|
workspacePath: expectedWorkspacePaths,
|
||||||
ppid: process.ppid,
|
ppid: process.ppid,
|
||||||
authToken: 'test-auth-token',
|
authToken: 'test-auth-token',
|
||||||
|
ideName: 'VS Code',
|
||||||
});
|
});
|
||||||
expect(fs.writeFile).toHaveBeenCalledWith(
|
expect(fs.writeFile).toHaveBeenCalledWith(
|
||||||
expectedLockFile,
|
expectedLockFile,
|
||||||
@@ -267,6 +271,7 @@ describe('IDEServer', () => {
|
|||||||
workspacePath: '/baz/qux',
|
workspacePath: '/baz/qux',
|
||||||
ppid: process.ppid,
|
ppid: process.ppid,
|
||||||
authToken: 'test-auth-token',
|
authToken: 'test-auth-token',
|
||||||
|
ideName: 'VS Code',
|
||||||
});
|
});
|
||||||
expect(fs.writeFile).toHaveBeenCalledWith(
|
expect(fs.writeFile).toHaveBeenCalledWith(
|
||||||
expectedLockFile,
|
expectedLockFile,
|
||||||
@@ -279,12 +284,7 @@ describe('IDEServer', () => {
|
|||||||
await ideServer.start(mockContext);
|
await ideServer.start(mockContext);
|
||||||
const replaceMock = mockContext.environmentVariableCollection.replace;
|
const replaceMock = mockContext.environmentVariableCollection.replace;
|
||||||
const port = getPortFromMock(replaceMock);
|
const port = getPortFromMock(replaceMock);
|
||||||
const lockFile = path.join(
|
const lockFile = path.join('/home/test', '.qwen', 'ide', `${port}.lock`);
|
||||||
'/home/test',
|
|
||||||
'.qwen',
|
|
||||||
'ide',
|
|
||||||
`${process.ppid}-${port}.lock`,
|
|
||||||
);
|
|
||||||
expect(fs.writeFile).toHaveBeenCalledWith(lockFile, expect.any(String));
|
expect(fs.writeFile).toHaveBeenCalledWith(lockFile, expect.any(String));
|
||||||
|
|
||||||
await ideServer.stop();
|
await ideServer.stop();
|
||||||
@@ -315,13 +315,14 @@ describe('IDEServer', () => {
|
|||||||
'/home/test',
|
'/home/test',
|
||||||
'.qwen',
|
'.qwen',
|
||||||
'ide',
|
'ide',
|
||||||
`${process.ppid}-${port}.lock`,
|
`${port}.lock`,
|
||||||
);
|
);
|
||||||
const expectedContent = JSON.stringify({
|
const expectedContent = JSON.stringify({
|
||||||
port: parseInt(port, 10),
|
port: parseInt(port, 10),
|
||||||
workspacePath: expectedWorkspacePaths,
|
workspacePath: expectedWorkspacePaths,
|
||||||
ppid: process.ppid,
|
ppid: process.ppid,
|
||||||
authToken: 'test-auth-token',
|
authToken: 'test-auth-token',
|
||||||
|
ideName: 'VS Code',
|
||||||
});
|
});
|
||||||
expect(fs.writeFile).toHaveBeenCalledWith(
|
expect(fs.writeFile).toHaveBeenCalledWith(
|
||||||
expectedLockFile,
|
expectedLockFile,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
IdeContextNotificationSchema,
|
IdeContextNotificationSchema,
|
||||||
OpenDiffRequestSchema,
|
OpenDiffRequestSchema,
|
||||||
} from '@qwen-code/qwen-code-core/src/ide/types.js';
|
} from '@qwen-code/qwen-code-core/src/ide/types.js';
|
||||||
|
import { detectIdeFromEnv } from '@qwen-code/qwen-code-core/src/ide/detect-ide.js';
|
||||||
import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
|
import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
|
||||||
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
||||||
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
||||||
@@ -82,11 +83,13 @@ async function writePortAndWorkspace({
|
|||||||
workspacePath,
|
workspacePath,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const ideInfo = detectIdeFromEnv();
|
||||||
const content = JSON.stringify({
|
const content = JSON.stringify({
|
||||||
port,
|
port,
|
||||||
workspacePath,
|
workspacePath,
|
||||||
ppid: process.ppid,
|
ppid: process.ppid,
|
||||||
authToken,
|
authToken,
|
||||||
|
ideName: ideInfo.displayName,
|
||||||
});
|
});
|
||||||
|
|
||||||
log(`Writing IDE lock file to: ${lockFile}`);
|
log(`Writing IDE lock file to: ${lockFile}`);
|
||||||
@@ -340,12 +343,8 @@ export class IDEServer {
|
|||||||
this.port = address.port;
|
this.port = address.port;
|
||||||
try {
|
try {
|
||||||
const ideDir = await getGlobalIdeDir();
|
const ideDir = await getGlobalIdeDir();
|
||||||
// Name the lock file by port to support multiple server instances
|
// Name the lock file by port to support multiple server instances.
|
||||||
// under the same parent process.
|
this.lockFile = path.join(ideDir, `${this.port}.lock`);
|
||||||
this.lockFile = path.join(
|
|
||||||
ideDir,
|
|
||||||
`${process.ppid}-${this.port}.lock`,
|
|
||||||
);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const message = err instanceof Error ? err.message : String(err);
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
this.log(`Failed to determine IDE lock directory: ${message}`);
|
this.log(`Failed to determine IDE lock directory: ${message}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user