feat(devtool): 脚本录制器的编辑器支持智能提示(LSP)

This commit is contained in:
XcantloadX 2025-02-04 20:28:38 +08:00
parent 3b225994d8
commit 496b10cac3
5 changed files with 336 additions and 40 deletions

View File

@ -13,6 +13,7 @@
"@types/node": "^22.12.0",
"ace-builds": "^1.37.5",
"ace-code": "^1.37.5",
"ace-linters": "^1.4.1",
"bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3",
"fabric": "^6.5.4",
@ -1830,6 +1831,75 @@
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
}
},
"node_modules/@vscode/l10n": {
"version": "0.0.18",
"resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz",
"integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="
},
"node_modules/@xml-tools/ast": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/@xml-tools/ast/-/ast-5.0.5.tgz",
"integrity": "sha512-avvzTOvGplCx9JSKdsTe3vK+ACvsHy2HxVfkcfIqPzu+kF5CT4rw5aUVzs0tJF4cnDyMRVkSyVxR07X0Px8gPA==",
"dependencies": {
"@xml-tools/common": "^0.1.6",
"@xml-tools/parser": "^1.0.11",
"lodash": "4.17.21"
}
},
"node_modules/@xml-tools/common": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@xml-tools/common/-/common-0.1.6.tgz",
"integrity": "sha512-7aVZeEYccs1KI/Asd6KKnrB4dTAWXTkjRMjG40ApGEUp5NpfQIvWLEBvMv85Koj2lbSpagcAERwDy9qMsfWGdA==",
"dependencies": {
"lodash": "4.17.21"
}
},
"node_modules/@xml-tools/constraints": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@xml-tools/constraints/-/constraints-1.1.1.tgz",
"integrity": "sha512-c9K/Ozmem2zbLta7HOjJpXszZA/UQkm3pKT3AAa+tKdnsIomPwcRXkltdd+UtdXcOTbqsuTV0fnSkLBgjlnxbQ==",
"dependencies": {
"@xml-tools/validation": "^1.0.16",
"lodash": "4.17.21"
}
},
"node_modules/@xml-tools/content-assist": {
"version": "3.1.11",
"resolved": "https://registry.npmjs.org/@xml-tools/content-assist/-/content-assist-3.1.11.tgz",
"integrity": "sha512-ExVgzRLutvBEMi0JQ8vi4ccao0lrq8DTsWKeAEH6/Zy2Wfp+XAR4ERNpFK7yp+QHQkWROr/XSNVarcTuopE+lg==",
"dependencies": {
"@xml-tools/common": "^0.1.6",
"@xml-tools/parser": "^1.0.11",
"lodash": "4.17.21"
}
},
"node_modules/@xml-tools/parser": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@xml-tools/parser/-/parser-1.0.11.tgz",
"integrity": "sha512-aKqQ077XnR+oQtHJlrAflaZaL7qZsulWc/i/ZEooar5JiWj1eLt0+Wg28cpa+XLney107wXqneC+oG1IZvxkTA==",
"dependencies": {
"chevrotain": "7.1.1"
}
},
"node_modules/@xml-tools/simple-schema": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@xml-tools/simple-schema/-/simple-schema-3.0.5.tgz",
"integrity": "sha512-8qrm23eGAFtvNWmJu46lttae+X8eOEPMXryf4JH6NBpFl1pphkNXqr7bAKnOjELmLPXHStoeKZO2vptyn4cPPA==",
"dependencies": {
"@xml-tools/ast": "^5.0.5",
"@xml-tools/content-assist": "^3.1.11",
"lodash": "4.17.21"
}
},
"node_modules/@xml-tools/validation": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/@xml-tools/validation/-/validation-1.0.16.tgz",
"integrity": "sha512-w/+kUYcxKXfQz8TQ3qAAuLl9N2WZ0HGiwI8nVuIe29dAZmyeXx5ZpODAW7yJoarH0/wZ+rhbc3XxbRqIPcSofA==",
"dependencies": {
"@xml-tools/ast": "^5.0.5",
"lodash": "4.17.21"
}
},
"node_modules/abab": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@ -1856,6 +1926,28 @@
"node": ">= 0.6.0"
}
},
"node_modules/ace-linters": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/ace-linters/-/ace-linters-1.4.1.tgz",
"integrity": "sha512-9YAW5d2+VW0irO8ogIrnviPbAHJbyfeFApFu0Xc3LrZIX8WQhktVUSXCxEAIHyJSTnOHnOkU+U+EzWgzNJ6egA==",
"dependencies": {
"@xml-tools/ast": "^5.0.5",
"@xml-tools/constraints": "^1.1.1",
"@xml-tools/parser": "^1.0.11",
"@xml-tools/simple-schema": "^3.0.5",
"htmlhint": "^1.1.4",
"luaparse": "latest",
"showdown": "latest",
"vscode-css-languageservice": "^6.2.6",
"vscode-html-languageservice": "^5.0.6",
"vscode-json-languageservice": "^5.4.1",
"vscode-languageserver-protocol": "^3.17.3",
"vscode-languageserver-textdocument": "^1.0.8",
"vscode-languageserver-types": "^3.17.3",
"vscode-uri": "^3.0.8",
"vscode-ws-jsonrpc": "^2.0.1"
}
},
"node_modules/acorn": {
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
@ -1940,7 +2032,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@ -1977,6 +2068,11 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"node_modules/async": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@ -2000,8 +2096,7 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"devOptional": true
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/bootstrap": {
"version": "5.3.3",
@ -2040,7 +2135,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"devOptional": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -2137,7 +2231,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@ -2149,6 +2242,14 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chevrotain": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.1.1.tgz",
"integrity": "sha512-wy3mC1x4ye+O+QkEinVJkPf5u2vsrDIYW9G7ZuwFl6v/Yu0LwUuT2POsb+NUWApebyxfkQq6+yDfRExbnI5rcw==",
"dependencies": {
"regexp-to-ast": "0.5.0"
}
},
"node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
@ -2167,7 +2268,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
@ -2178,8 +2278,7 @@
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/color-support": {
"version": "1.1.3",
@ -2202,11 +2301,18 @@
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "9.5.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
"engines": {
"node": "^12.20.0 || >=14"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"devOptional": true
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/console-control-strings": {
"version": "1.1.0",
@ -2886,8 +2992,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"optional": true
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/fsevents": {
"version": "2.3.3",
@ -2946,7 +3051,6 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
"optional": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@ -2996,7 +3100,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -3038,6 +3141,32 @@
"node": ">=12"
}
},
"node_modules/htmlhint": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-1.1.4.tgz",
"integrity": "sha512-tSKPefhIaaWDk/vKxAOQbN+QwZmDeJCq3bZZGbJMoMQAfTjepudC+MkuT9MOBbuQI3dLLzDWbmU7fLV3JASC7Q==",
"dependencies": {
"async": "3.2.3",
"chalk": "^4.1.2",
"commander": "^9.1.0",
"glob": "^7.2.0",
"is-glob": "^4.0.3",
"node-fetch": "^2.6.2",
"strip-json-comments": "3.1.0",
"xml": "1.0.1"
},
"bin": {
"htmlhint": "bin/htmlhint"
}
},
"node_modules/htmlhint/node_modules/strip-json-comments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
"integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
"engines": {
"node": ">=8"
}
},
"node_modules/http-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
@ -3124,7 +3253,6 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"optional": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@ -3133,8 +3261,7 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"optional": true
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/invariant": {
"version": "2.2.4",
@ -3167,7 +3294,6 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -3185,7 +3311,6 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
@ -3322,6 +3447,11 @@
"node": ">=6"
}
},
"node_modules/jsonc-parser": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
"integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@ -3364,6 +3494,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
@ -3402,6 +3537,14 @@
"yallist": "^3.0.2"
}
},
"node_modules/luaparse": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/luaparse/-/luaparse-0.3.1.tgz",
"integrity": "sha512-b21h2bFEbtGXmVqguHogbyrMAA0wOHyp9u/rx+w6Yc9pW1t9YjhGUsp87lYcp7pFRqSWN/PhFkrdIqKEUzRjjQ==",
"bin": {
"luaparse": "bin/luaparse"
}
},
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@ -3476,7 +3619,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"devOptional": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -3575,7 +3717,6 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"optional": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
@ -3594,20 +3735,17 @@
"node_modules/node-fetch/node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"optional": true
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/node-fetch/node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"optional": true
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/node-fetch/node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"optional": true,
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
@ -3665,7 +3803,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"optional": true,
"dependencies": {
"wrappy": "1"
}
@ -3770,7 +3907,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
@ -4088,6 +4224,11 @@
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/regexp-to-ast": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz",
"integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw=="
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@ -4295,6 +4436,21 @@
"node": ">=8"
}
},
"node_modules/showdown": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz",
"integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==",
"dependencies": {
"commander": "^9.0.0"
},
"bin": {
"showdown": "bin/showdown.js"
},
"funding": {
"type": "individual",
"url": "https://www.paypal.me/tiviesantos"
}
},
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@ -4405,7 +4561,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@ -4736,6 +4891,92 @@
}
}
},
"node_modules/vscode-css-languageservice": {
"version": "6.3.2",
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.2.tgz",
"integrity": "sha512-GEpPxrUTAeXWdZWHev1OJU9lz2Q2/PPBxQ2TIRmLGvQiH3WZbqaNoute0n0ewxlgtjzTW3AKZT+NHySk5Rf4Eg==",
"dependencies": {
"@vscode/l10n": "^0.0.18",
"vscode-languageserver-textdocument": "^1.0.12",
"vscode-languageserver-types": "3.17.5",
"vscode-uri": "^3.0.8"
}
},
"node_modules/vscode-html-languageservice": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.3.1.tgz",
"integrity": "sha512-ysUh4hFeW/WOWz/TO9gm08xigiSsV/FOAZ+DolgJfeLftna54YdmZ4A+lIn46RbdO3/Qv5QHTn1ZGqmrXQhZyA==",
"dependencies": {
"@vscode/l10n": "^0.0.18",
"vscode-languageserver-textdocument": "^1.0.12",
"vscode-languageserver-types": "^3.17.5",
"vscode-uri": "^3.0.8"
}
},
"node_modules/vscode-json-languageservice": {
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.4.3.tgz",
"integrity": "sha512-NVSEQDloP9NYccuqKg4eI46kutZpwucBY4csBB6FCxbM7AZVoBt0oxTItPVA+ZwhnG1bg/fmiBRAwcGJyNQoPA==",
"dependencies": {
"@vscode/l10n": "^0.0.18",
"jsonc-parser": "^3.3.1",
"vscode-languageserver-textdocument": "^1.0.12",
"vscode-languageserver-types": "^3.17.5",
"vscode-uri": "^3.0.8"
}
},
"node_modules/vscode-jsonrpc": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
"integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/vscode-languageserver-protocol": {
"version": "3.17.5",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
"integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
"dependencies": {
"vscode-jsonrpc": "8.2.0",
"vscode-languageserver-types": "3.17.5"
}
},
"node_modules/vscode-languageserver-textdocument": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
"integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="
},
"node_modules/vscode-languageserver-types": {
"version": "3.17.5",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
},
"node_modules/vscode-uri": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
"integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="
},
"node_modules/vscode-ws-jsonrpc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/vscode-ws-jsonrpc/-/vscode-ws-jsonrpc-2.0.2.tgz",
"integrity": "sha512-gIOGdaWwKYwwqohgeRC8AtqqHSNghK8wA3oVcBi7UMAdZnRSAf8n4/Svtd+JHqGiIguYdNa/sC0s4IW3ZDF7mA==",
"dependencies": {
"vscode-jsonrpc": "8.0.2"
},
"engines": {
"node": ">=16.11.0",
"npm": ">=8.0.0"
}
},
"node_modules/vscode-ws-jsonrpc/node_modules/vscode-jsonrpc": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz",
"integrity": "sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/w3c-xmlserializer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
@ -4835,8 +5076,7 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"optional": true
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/ws": {
"version": "8.18.0",
@ -4859,6 +5099,11 @@
}
}
},
"node_modules/xml": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
"integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw=="
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",

View File

@ -15,6 +15,7 @@
"@types/node": "^22.12.0",
"ace-builds": "^1.37.5",
"ace-code": "^1.37.5",
"ace-linters": "^1.4.1",
"bootstrap": "^5.3.3",
"bootstrap-icons": "^1.11.3",
"fabric": "^6.5.4",

View File

@ -20,10 +20,25 @@ import { useToast } from '../../components/ToastMessage';
import { ScriptRecorderStorage } from '../../utils/storageUtils';
// 引入 ace 编辑器的主题和语言模式
import modePython from 'ace-builds/src-noconflict/mode-python?url';
import themeMonokai from 'ace-builds/src-noconflict/theme-monokai?url';
import themeChrome from 'ace-builds/src-noconflict/theme-chrome?url';
import extLanguageTools from 'ace-builds/src-noconflict/ext-language_tools?url';
import 'ace-builds/src-noconflict/mode-python';
import 'ace-builds/src-noconflict/theme-monokai';
import 'ace-builds/src-noconflict/theme-chrome';
import 'ace-builds/src-noconflict/ext-language_tools';
// LSP
import { AceLanguageClient } from "ace-linters/build/ace-language-client";
import { config } from "ace-builds";
import { LanguageProvider } from 'ace-linters/types/language-provider';
import { Ace } from 'ace-code';
// https://github.com/ajaxorg/ace/issues/4597
config.setModuleUrl('ace/mode/python', modePython);
config.setModuleUrl('ace/theme/monokai', themeMonokai);
config.setModuleUrl('ace/theme/chrome', themeChrome);
config.setModuleUrl('ace/ext/language_tools', extLanguageTools);
const Container = styled.div`
display: flex;
@ -78,7 +93,6 @@ ContextStackVars.screenshot_mode = 'manual'
device.screenshot()
`
console.log('ScriptRecorderStorage.load()', ScriptRecorderStorage.loadCode());
const useScriptRecorderStore = create<ScriptRecorderState>((set) => ({
code: ScriptRecorderStorage.loadCode() || DEFAULT_CODE,
tool: 'drag',
@ -96,10 +110,10 @@ const useScriptRecorderStore = create<ScriptRecorderState>((set) => ({
setCode: (code) => {
ScriptRecorderStorage.saveCode(code);
console.log('setCode', code);
set({ code });
},
setTool: (tool) => set({ tool }),
setAutoScreenshot: (auto) => set({ autoScreenshot: auto }),
setConnected: (connected) => set({ connected }),
setImageUrl: (url) => set({ imageUrl: url }),
@ -402,8 +416,8 @@ function useStoreImageMetaData() {
const ScriptRecorder: React.FC = () => {
const client = useDebugClient();
const { showToast, ToastComponent } = useToast();
const editorRef = useRef<any>(null);
const editorRef = useRef<AceEditor>(null);
const lspRef = useRef<LanguageProvider | null>(null);
const { imageMetaData, Definitions, Annotations, clear } = useStoreImageMetaData();
const code = useScriptRecorderStore((s) => s.code);
const tool = useScriptRecorderStore((s) => s.tool);
@ -452,11 +466,13 @@ const ScriptRecorder: React.FC = () => {
}, 10);
});
// 自动截图
useEffect(() => {
if (autoScreenshot)
updateScreenshot();
}, [autoScreenshot, updateScreenshot]);
// 初始化:连接事件
useEffect(() => {
client.addEventListener('connectionStatus', (e) => {
if (e.connected) {
@ -466,6 +482,29 @@ const ScriptRecorder: React.FC = () => {
});
}, [client]);
// 初始化LSP
useEffect(() => {
if (!editorRef.current || !editorRef.current.editor)
return;
const editor = editorRef.current.editor as unknown as Ace.Editor;
const serverData = {
module: () => import("ace-linters/build/language-client"),
modes: "python",
type: "socket",
socket: new WebSocket("ws://127.0.0.1:5479"),
} as const;
// AceLanguageClient 重复初始化似乎有 bug
// 用 ref 缓存,避免 StrictMode 下重复初始化
const lsp = lspRef.current || AceLanguageClient.for(serverData);
lspRef.current = lsp;
lsp.registerEditor(editor);
}, []);
const handleAnnotationChange = async (e: AnnotationChangedEvent) => {
if (e.type === 'add') {
@ -651,6 +690,7 @@ const ScriptRecorder: React.FC = () => {
value={code}
onChange={setCode}
name="script-editor"
width="100%"
height="100%"
fontSize={14}
@ -660,10 +700,10 @@ const ScriptRecorder: React.FC = () => {
setOptions={{
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
showLineNumbers: true,
tabSize: 4,
}}
/>
</CodeEditorWrapper>
</Splitable>

View File

@ -2,8 +2,11 @@ import time
import asyncio
import threading
import traceback
import subprocess
from io import StringIO
from pathlib import Path
from collections import deque
from contextlib import redirect_stdout
import cv2
from pydantic import BaseModel
@ -93,11 +96,14 @@ class RunCodeRequest(BaseModel):
@app.post("/api/code/run")
async def run_code(request: RunCodeRequest):
stdout = StringIO()
code = f"from kotonebot import *\n" + request.code
try:
with manual_context():
ret = exec(code)
return {"status": "ok", "result": ret}
with redirect_stdout(stdout):
ret = exec(code)
return {"status": "ok", "result": stdout.getvalue()}
except Exception as e:
return {"status": "error", "message": str(e), "traceback": traceback.format_exc()}
@ -159,4 +165,7 @@ if __name__ == "__main__":
from kotonebot.backend.context import init_context
init_context()
vars.debug.hide_server_log = False
process = subprocess.Popen(["pylsp", "--port", "5479", "--ws"])
print("LSP started. PID=", process.pid)
uvicorn.run(app, host="127.0.0.1", port=8000, log_level='critical' if vars.debug.hide_server_log else None)
process.kill()

View File

@ -3,3 +3,4 @@ jinja2==3.1.5
pyinstaller==6.11.1
twine==6.1.0
dataclasses-json==0.6.7
python-lsp-server==1.12.0