Merge branch 'covespace:main' into message-handler
This commit is contained in:
commit
d2c0ee9d02
10
.chat/instructions/commit_message/instCommitMessage.txt
Normal file
10
.chat/instructions/commit_message/instCommitMessage.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
As a software developer assistant, your task is to provide clear and concise responses and write commit messages based on given code, requirements, or conversations. Follow these guidelines:
|
||||||
|
|
||||||
|
1. A commit message should include a title and multiple body lines.
|
||||||
|
2. Adhere to best practices, such as keeping titles under 50 characters and limiting body lines to under 72 characters.
|
||||||
|
3. Enclose messages in code blocks using triple backticks (```).
|
||||||
|
4. Utilize the <context>, if provided, to create the summary.
|
||||||
|
5. Utilize the previous messages, if provided in the end of this prompt, to create the summary. Note that not all previous messages are necessarily relevant.
|
||||||
|
6. Please output commit message in a markdown code block, flag as commitmsg type.
|
||||||
|
|
||||||
|
If you need more information, feel free to ask.
|
22
.chat/instructions/default/instCode.txt
Normal file
22
.chat/instructions/default/instCode.txt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
As a software developer assistant, your tasks are to:
|
||||||
|
|
||||||
|
- Provide a clear and concise response to address the user's <request>.
|
||||||
|
- Write code and give advice based on given code or information in the <context> if provided.
|
||||||
|
- Follow language-specific best practices and coding standards.
|
||||||
|
|
||||||
|
When responding:
|
||||||
|
|
||||||
|
1. Summarize and describe the requirements or provided information in your own words.
|
||||||
|
2. The summary and description should better be written in bullet points (excluding code).
|
||||||
|
3. If modifying given code, output the changes and avoid unnecessary unchanged code.
|
||||||
|
4. Enclose code or changes within blocks using triple backticks (```), and include the programming language and the file path, if available. For example:
|
||||||
|
```
|
||||||
|
```python path=./path/to/file.py
|
||||||
|
print("Hello, World!")
|
||||||
|
```
|
||||||
|
```
|
||||||
|
If no file paths or folder structure are provided and you are unsure about the file path of the code, you may omit the file path.
|
||||||
|
5. Use separate code blocks for different files.
|
||||||
|
6. Utilize the previous messages, if provided in the end of this prompt, to create your response. Note that not all previous messages are necessarily relevant.
|
||||||
|
7. When providing a suggestion or instruction, begin by explaining the reason behind it.
|
||||||
|
8. If you need more information, ask for it.
|
1
.chat/instructions/default/instLangPython.txt
Normal file
1
.chat/instructions/default/instLangPython.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
When writing Python code, include type hints where appropriate and maintain compliance with PEP-8 guidelines, such as providing docstrings for modules, classes, and functions.
|
469
package-lock.json
generated
469
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "devchat",
|
"name": "devchat",
|
||||||
"version": "0.0.1",
|
"version": "0.0.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "devchat",
|
"name": "devchat",
|
||||||
"version": "0.0.1",
|
"version": "0.0.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.10.8",
|
"@emotion/react": "^11.10.8",
|
||||||
"@mantine/core": "^6.0.10",
|
"@mantine/core": "^6.0.10",
|
||||||
@ -36,7 +36,6 @@
|
|||||||
"@babel/preset-typescript": "^7.21.5",
|
"@babel/preset-typescript": "^7.21.5",
|
||||||
"@types/glob": "^8.1.0",
|
"@types/glob": "^8.1.0",
|
||||||
"@types/jest": "^29.5.1",
|
"@types/jest": "^29.5.1",
|
||||||
"@types/mocha": "^10.0.1",
|
|
||||||
"@types/ncp": "^2.0.5",
|
"@types/ncp": "^2.0.5",
|
||||||
"@types/node": "16.x",
|
"@types/node": "16.x",
|
||||||
"@types/react-dom": "^18.2.3",
|
"@types/react-dom": "^18.2.3",
|
||||||
@ -55,7 +54,6 @@
|
|||||||
"html-webpack-plugin": "^5.5.1",
|
"html-webpack-plugin": "^5.5.1",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"json-loader": "^0.5.7",
|
"json-loader": "^0.5.7",
|
||||||
"mocha": "^10.2.0",
|
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
@ -3770,12 +3768,6 @@
|
|||||||
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
|
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/mocha": {
|
|
||||||
"version": "10.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz",
|
|
||||||
"integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/ncp": {
|
"node_modules/@types/ncp": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ncp/-/ncp-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ncp/-/ncp-2.0.5.tgz",
|
||||||
@ -4491,15 +4483,6 @@
|
|||||||
"ajv": "^6.9.1"
|
"ajv": "^6.9.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ansi-colors": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ansi-escapes": {
|
"node_modules/ansi-escapes": {
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
||||||
@ -5007,12 +4990,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browser-stdout": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.21.5",
|
"version": "4.21.5",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
|
||||||
@ -5289,17 +5266,6 @@
|
|||||||
"node": ">= 10.0"
|
"node": ">= 10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cliui": {
|
|
||||||
"version": "7.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
|
||||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"string-width": "^4.2.0",
|
|
||||||
"strip-ansi": "^6.0.0",
|
|
||||||
"wrap-ansi": "^7.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/clone-deep": {
|
"node_modules/clone-deep": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
||||||
@ -5779,18 +5745,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/decamelize": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dedent": {
|
"node_modules/dedent": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
|
||||||
@ -5879,15 +5833,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
|
||||||
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
|
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
|
||||||
},
|
},
|
||||||
"node_modules/diff": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.3.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/diff-sequences": {
|
"node_modules/diff-sequences": {
|
||||||
"version": "29.4.3",
|
"version": "29.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz",
|
||||||
@ -6742,15 +6687,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flat": {
|
|
||||||
"version": "5.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
|
||||||
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
|
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
|
||||||
"flat": "cli.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/flat-cache": {
|
"node_modules/flat-cache": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
||||||
@ -7649,18 +7585,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-unicode-supported": {
|
|
||||||
"version": "0.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
|
||||||
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-wsl": {
|
"node_modules/is-wsl": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||||
@ -8688,22 +8612,6 @@
|
|||||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/log-symbols": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"chalk": "^4.1.0",
|
|
||||||
"is-unicode-supported": "^0.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/loose-envify": {
|
"node_modules/loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
@ -9064,120 +8972,6 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mocha": {
|
|
||||||
"version": "10.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
|
|
||||||
"integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"ansi-colors": "4.1.1",
|
|
||||||
"browser-stdout": "1.3.1",
|
|
||||||
"chokidar": "3.5.3",
|
|
||||||
"debug": "4.3.4",
|
|
||||||
"diff": "5.0.0",
|
|
||||||
"escape-string-regexp": "4.0.0",
|
|
||||||
"find-up": "5.0.0",
|
|
||||||
"glob": "7.2.0",
|
|
||||||
"he": "1.2.0",
|
|
||||||
"js-yaml": "4.1.0",
|
|
||||||
"log-symbols": "4.1.0",
|
|
||||||
"minimatch": "5.0.1",
|
|
||||||
"ms": "2.1.3",
|
|
||||||
"nanoid": "3.3.3",
|
|
||||||
"serialize-javascript": "6.0.0",
|
|
||||||
"strip-json-comments": "3.1.1",
|
|
||||||
"supports-color": "8.1.1",
|
|
||||||
"workerpool": "6.2.1",
|
|
||||||
"yargs": "16.2.0",
|
|
||||||
"yargs-parser": "20.2.4",
|
|
||||||
"yargs-unparser": "2.0.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"_mocha": "bin/_mocha",
|
|
||||||
"mocha": "bin/mocha.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/mochajs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/glob": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
|
||||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^3.0.4",
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"path-is-absolute": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/glob/node_modules/minimatch": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^1.1.7"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/minimatch": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/ms": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/supports-color": {
|
|
||||||
"version": "8.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
|
||||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@ -9196,18 +8990,6 @@
|
|||||||
"multicast-dns": "cli.js"
|
"multicast-dns": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
|
||||||
"version": "3.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
|
|
||||||
"integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
|
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
|
||||||
"nanoid": "bin/nanoid.cjs"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/natural-compare": {
|
"node_modules/natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
@ -12597,12 +12379,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/workerpool": {
|
|
||||||
"version": "6.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
|
|
||||||
"integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/wrap-ansi": {
|
"node_modules/wrap-ansi": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
@ -12691,48 +12467,6 @@
|
|||||||
"node": ">= 6"
|
"node": ">= 6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/yargs": {
|
|
||||||
"version": "16.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
|
||||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"cliui": "^7.0.2",
|
|
||||||
"escalade": "^3.1.1",
|
|
||||||
"get-caller-file": "^2.0.5",
|
|
||||||
"require-directory": "^2.1.1",
|
|
||||||
"string-width": "^4.2.0",
|
|
||||||
"y18n": "^5.0.5",
|
|
||||||
"yargs-parser": "^20.2.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yargs-parser": {
|
|
||||||
"version": "20.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
|
|
||||||
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yargs-unparser": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"camelcase": "^6.0.0",
|
|
||||||
"decamelize": "^4.0.0",
|
|
||||||
"flat": "^5.0.2",
|
|
||||||
"is-plain-obj": "^2.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yocto-queue": {
|
"node_modules/yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
@ -15449,12 +15183,6 @@
|
|||||||
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
|
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/mocha": {
|
|
||||||
"version": "10.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz",
|
|
||||||
"integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/ncp": {
|
"@types/ncp": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ncp/-/ncp-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ncp/-/ncp-2.0.5.tgz",
|
||||||
@ -16023,12 +15751,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"ansi-colors": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"ansi-escapes": {
|
"ansi-escapes": {
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
||||||
@ -16425,12 +16147,6 @@
|
|||||||
"fill-range": "^7.0.1"
|
"fill-range": "^7.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"browser-stdout": {
|
|
||||||
"version": "1.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
|
|
||||||
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"version": "4.21.5",
|
"version": "4.21.5",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
|
||||||
@ -16607,17 +16323,6 @@
|
|||||||
"source-map": "~0.6.0"
|
"source-map": "~0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cliui": {
|
|
||||||
"version": "7.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
|
||||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"string-width": "^4.2.0",
|
|
||||||
"strip-ansi": "^6.0.0",
|
|
||||||
"wrap-ansi": "^7.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"clone-deep": {
|
"clone-deep": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
||||||
@ -16969,12 +16674,6 @@
|
|||||||
"ms": "2.1.2"
|
"ms": "2.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"decamelize": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"dedent": {
|
"dedent": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
|
||||||
@ -17041,12 +16740,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
|
||||||
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
|
"integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
|
||||||
},
|
},
|
||||||
"diff": {
|
|
||||||
"version": "5.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
|
||||||
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"diff-sequences": {
|
"diff-sequences": {
|
||||||
"version": "29.4.3",
|
"version": "29.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz",
|
||||||
@ -17699,12 +17392,6 @@
|
|||||||
"path-exists": "^4.0.0"
|
"path-exists": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flat": {
|
|
||||||
"version": "5.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
|
|
||||||
"integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"flat-cache": {
|
"flat-cache": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
|
||||||
@ -18337,12 +18024,6 @@
|
|||||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-unicode-supported": {
|
|
||||||
"version": "0.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
|
||||||
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"is-wsl": {
|
"is-wsl": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||||
@ -19151,16 +18832,6 @@
|
|||||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"log-symbols": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"chalk": "^4.1.0",
|
|
||||||
"is-unicode-supported": "^0.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"loose-envify": {
|
"loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
@ -19432,97 +19103,6 @@
|
|||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mocha": {
|
|
||||||
"version": "10.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
|
|
||||||
"integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ansi-colors": "4.1.1",
|
|
||||||
"browser-stdout": "1.3.1",
|
|
||||||
"chokidar": "3.5.3",
|
|
||||||
"debug": "4.3.4",
|
|
||||||
"diff": "5.0.0",
|
|
||||||
"escape-string-regexp": "4.0.0",
|
|
||||||
"find-up": "5.0.0",
|
|
||||||
"glob": "7.2.0",
|
|
||||||
"he": "1.2.0",
|
|
||||||
"js-yaml": "4.1.0",
|
|
||||||
"log-symbols": "4.1.0",
|
|
||||||
"minimatch": "5.0.1",
|
|
||||||
"ms": "2.1.3",
|
|
||||||
"nanoid": "3.3.3",
|
|
||||||
"serialize-javascript": "6.0.0",
|
|
||||||
"strip-json-comments": "3.1.1",
|
|
||||||
"supports-color": "8.1.1",
|
|
||||||
"workerpool": "6.2.1",
|
|
||||||
"yargs": "16.2.0",
|
|
||||||
"yargs-parser": "20.2.4",
|
|
||||||
"yargs-unparser": "2.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"glob": {
|
|
||||||
"version": "7.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
|
||||||
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^3.0.4",
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"path-is-absolute": "^1.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"minimatch": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"brace-expansion": "^1.1.7"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minimatch": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"brace-expansion": "^2.0.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"brace-expansion": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"balanced-match": "^1.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "8.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
|
||||||
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
@ -19538,12 +19118,6 @@
|
|||||||
"thunky": "^1.0.2"
|
"thunky": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nanoid": {
|
|
||||||
"version": "3.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
|
|
||||||
"integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"natural-compare": {
|
"natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
@ -22033,12 +21607,6 @@
|
|||||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"workerpool": {
|
|
||||||
"version": "6.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
|
|
||||||
"integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"wrap-ansi": {
|
"wrap-ansi": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||||
@ -22095,39 +21663,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
|
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
|
||||||
},
|
},
|
||||||
"yargs": {
|
|
||||||
"version": "16.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
|
||||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"cliui": "^7.0.2",
|
|
||||||
"escalade": "^3.1.1",
|
|
||||||
"get-caller-file": "^2.0.5",
|
|
||||||
"require-directory": "^2.1.1",
|
|
||||||
"string-width": "^4.2.0",
|
|
||||||
"y18n": "^5.0.5",
|
|
||||||
"yargs-parser": "^20.2.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yargs-parser": {
|
|
||||||
"version": "20.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
|
|
||||||
"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"yargs-unparser": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"camelcase": "^6.0.0",
|
|
||||||
"decamelize": "^4.0.0",
|
|
||||||
"flat": "^5.0.2",
|
|
||||||
"is-plain-obj": "^2.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yocto-queue": {
|
"yocto-queue": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"name": "devchat",
|
"name": "devchat",
|
||||||
"displayName": "devchat",
|
"displayName": "devchat",
|
||||||
"description": "devchat",
|
"description": "devchat",
|
||||||
"version": "0.0.1",
|
"version": "0.0.3",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.77.0"
|
"vscode": "^1.77.0"
|
||||||
},
|
},
|
||||||
@ -24,7 +24,9 @@
|
|||||||
"DevChat.llmModel": {
|
"DevChat.llmModel": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "OpenAI",
|
"default": "OpenAI",
|
||||||
"enum": ["OpenAI"],
|
"enum": [
|
||||||
|
"OpenAI"
|
||||||
|
],
|
||||||
"description": "Select whose llm to use."
|
"description": "Select whose llm to use."
|
||||||
},
|
},
|
||||||
"DevChat.OpenAI.model": {
|
"DevChat.OpenAI.model": {
|
||||||
@ -123,7 +125,6 @@
|
|||||||
"@babel/preset-typescript": "^7.21.5",
|
"@babel/preset-typescript": "^7.21.5",
|
||||||
"@types/glob": "^8.1.0",
|
"@types/glob": "^8.1.0",
|
||||||
"@types/jest": "^29.5.1",
|
"@types/jest": "^29.5.1",
|
||||||
"@types/mocha": "^10.0.1",
|
|
||||||
"@types/ncp": "^2.0.5",
|
"@types/ncp": "^2.0.5",
|
||||||
"@types/node": "16.x",
|
"@types/node": "16.x",
|
||||||
"@types/react-dom": "^18.2.3",
|
"@types/react-dom": "^18.2.3",
|
||||||
@ -142,7 +143,6 @@
|
|||||||
"html-webpack-plugin": "^5.5.1",
|
"html-webpack-plugin": "^5.5.1",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"json-loader": "^0.5.7",
|
"json-loader": "^0.5.7",
|
||||||
"mocha": "^10.2.0",
|
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
|
107
src/chatPanel.ts
107
src/chatPanel.ts
@ -1,107 +0,0 @@
|
|||||||
// chatPanel.ts
|
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import DevChat from './devchat';
|
|
||||||
import handleMessage from './messageHandler';
|
|
||||||
|
|
||||||
export default class ChatPanel {
|
|
||||||
private static _instance: ChatPanel | undefined;
|
|
||||||
private readonly _panel: vscode.WebviewPanel;
|
|
||||||
private _disposables: vscode.Disposable[] = [];
|
|
||||||
|
|
||||||
// Create or reveal the chat panel
|
|
||||||
public static createOrShow(extensionUri: vscode.Uri) {
|
|
||||||
if (ChatPanel._instance) {
|
|
||||||
ChatPanel._instance._panel.reveal();
|
|
||||||
} else {
|
|
||||||
const panel = ChatPanel.createWebviewPanel(extensionUri);
|
|
||||||
ChatPanel._instance = new ChatPanel(panel, extensionUri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static currentPanel(): ChatPanel | undefined {
|
|
||||||
return ChatPanel._instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new webview panel
|
|
||||||
private static createWebviewPanel(extensionUri: vscode.Uri): vscode.WebviewPanel {
|
|
||||||
const column = vscode.window.activeTextEditor
|
|
||||||
? vscode.window.activeTextEditor.viewColumn
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return vscode.window.createWebviewPanel(
|
|
||||||
'chatPanel',
|
|
||||||
'Chat',
|
|
||||||
column || vscode.ViewColumn.One,
|
|
||||||
{
|
|
||||||
enableScripts: true,
|
|
||||||
localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'dist')],
|
|
||||||
retainContextWhenHidden: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
|
|
||||||
this._panel = panel;
|
|
||||||
|
|
||||||
this.setWebviewOptions(extensionUri);
|
|
||||||
this.setWebviewContent(extensionUri);
|
|
||||||
this.registerEventListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set webview options
|
|
||||||
private setWebviewOptions(extensionUri: vscode.Uri) {
|
|
||||||
this._panel.webview.options = {
|
|
||||||
enableScripts: true,
|
|
||||||
localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'dist')],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set webview content
|
|
||||||
private setWebviewContent(extensionUri: vscode.Uri) {
|
|
||||||
this._panel.webview.html = this._getHtmlContent(extensionUri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public panel(): vscode.WebviewPanel {
|
|
||||||
return this._panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register event listeners for the panel and webview
|
|
||||||
private registerEventListeners() {
|
|
||||||
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
|
|
||||||
|
|
||||||
this._panel.webview.onDidReceiveMessage(
|
|
||||||
async (message) => {
|
|
||||||
handleMessage(message, this._panel);
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
this._disposables
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the HTML content for the panel
|
|
||||||
private _getHtmlContent(extensionUri: vscode.Uri): string {
|
|
||||||
const htmlPath = vscode.Uri.joinPath(extensionUri, 'dist', 'assets', 'chatPanel.html');
|
|
||||||
// const htmlPath = vscode.Uri.joinPath(extensionUri, 'dist', 'index.html');
|
|
||||||
const htmlContent = fs.readFileSync(htmlPath.fsPath, 'utf8');
|
|
||||||
|
|
||||||
return htmlContent.replace(/<vscode-resource:(\/.+?)>/g, (_, resourcePath) => {
|
|
||||||
const resourceUri = vscode.Uri.joinPath(extensionUri, 'dist', resourcePath);
|
|
||||||
return this._panel.webview.asWebviewUri(resourceUri).toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dispose the panel and clean up resources
|
|
||||||
public dispose() {
|
|
||||||
ChatPanel._instance = undefined;
|
|
||||||
this._panel.dispose();
|
|
||||||
while (this._disposables.length) {
|
|
||||||
const disposable = this._disposables.pop();
|
|
||||||
if (disposable) {
|
|
||||||
disposable.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,8 +7,8 @@ import * as fs from 'fs';
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
import { createTempSubdirectory } from './commonUtil';
|
import { createTempSubdirectory } from '../util/commonUtil';
|
||||||
import ExtensionContextHolder from './extensionContext';
|
import ExtensionContextHolder from '../util/extensionContext';
|
||||||
|
|
||||||
const mkdirAsync = promisify(fs.mkdir);
|
const mkdirAsync = promisify(fs.mkdir);
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { createTempSubdirectory, getLanguageIdByFileName } from './commonUtil';
|
import { createTempSubdirectory, getLanguageIdByFileName } from '../util/commonUtil';
|
||||||
|
|
||||||
export async function handleCodeSelected(fileSelected: string, codeSelected: string) {
|
export async function handleCodeSelected(fileSelected: string, codeSelected: string) {
|
||||||
// get file name from fileSelected
|
// get file name from fileSelected
|
@ -1,7 +1,7 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { ChatContext } from './contextManager';
|
import { ChatContext } from './contextManager';
|
||||||
import { createTempSubdirectory, runCommandAndWriteOutput, runCommandStringAndWriteOutput } from './commonUtil';
|
import { createTempSubdirectory, runCommandAndWriteOutput, runCommandStringAndWriteOutput } from '../util/commonUtil';
|
||||||
|
|
||||||
export const customCommandContext: ChatContext = {
|
export const customCommandContext: ChatContext = {
|
||||||
name: '<custom command>',
|
name: '<custom command>',
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { createTempSubdirectory, getLanguageIdByFileName } from './commonUtil';
|
import { createTempSubdirectory, getLanguageIdByFileName } from '../util/commonUtil';
|
||||||
|
|
||||||
export async function handleFileSelected(fileSelected: string) {
|
export async function handleFileSelected(fileSelected: string) {
|
||||||
// get file name from fileSelected
|
// get file name from fileSelected
|
@ -1,6 +1,6 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { ChatContext } from './contextManager';
|
import { ChatContext } from './contextManager';
|
||||||
import { createTempSubdirectory, runCommandAndWriteOutput } from './commonUtil';
|
import { createTempSubdirectory, runCommandAndWriteOutput } from '../util/commonUtil';
|
||||||
|
|
||||||
export const gitDiffContext: ChatContext = {
|
export const gitDiffContext: ChatContext = {
|
||||||
name: 'git diff',
|
name: 'git diff',
|
@ -1,6 +1,6 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { ChatContext } from './contextManager';
|
import { ChatContext } from './contextManager';
|
||||||
import { createTempSubdirectory, runCommandAndWriteOutput } from './commonUtil';
|
import { createTempSubdirectory, runCommandAndWriteOutput } from '../util/commonUtil';
|
||||||
|
|
||||||
export const gitDiffCachedContext: ChatContext = {
|
export const gitDiffCachedContext: ChatContext = {
|
||||||
name: 'git diff cached',
|
name: 'git diff cached',
|
73
src/contributes/commands.ts
Normal file
73
src/contributes/commands.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import ChatPanel from '../panel/chatPanel';
|
||||||
|
import { sendFileSelectMessage, sendCodeSelectMessage } from './util';
|
||||||
|
|
||||||
|
function registerOpenChatPanelCommand(context: vscode.ExtensionContext) {
|
||||||
|
let disposable = vscode.commands.registerCommand('devchat.openChatPanel', () => {
|
||||||
|
if (vscode.workspace.workspaceFolders) {
|
||||||
|
ChatPanel.createOrShow(context.extensionUri);
|
||||||
|
} else {
|
||||||
|
vscode.window.showErrorMessage('Please open a directory before using the chat panel.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
context.subscriptions.push(disposable);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureChatPanel(context: vscode.ExtensionContext): boolean {
|
||||||
|
if (!ChatPanel.currentPanel()) {
|
||||||
|
if (vscode.workspace.workspaceFolders) {
|
||||||
|
ChatPanel.createOrShow(context.extensionUri);
|
||||||
|
} else {
|
||||||
|
vscode.window.showErrorMessage('Please open a directory before using the chat panel.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerAddContextCommand(context: vscode.ExtensionContext) {
|
||||||
|
const disposable_add_context = vscode.commands.registerCommand('devchat.addConext', async (uri: { path: any; }) => {
|
||||||
|
if (!ensureChatPanel(context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await sendFileSelectMessage(ChatPanel.currentPanel()!.panel(), uri.path);
|
||||||
|
});
|
||||||
|
context.subscriptions.push(disposable_add_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerAskForCodeCommand(context: vscode.ExtensionContext) {
|
||||||
|
const disposableCodeContext = vscode.commands.registerCommand('devchat.askForCode', async () => {
|
||||||
|
const editor = vscode.window.activeTextEditor;
|
||||||
|
if (editor) {
|
||||||
|
if (!ensureChatPanel(context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedText = editor.document.getText(editor.selection);
|
||||||
|
await sendCodeSelectMessage(ChatPanel.currentPanel()!.panel(), editor.document.fileName, selectedText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
context.subscriptions.push(disposableCodeContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerAskForFileCommand(context: vscode.ExtensionContext) {
|
||||||
|
const disposableAskFile = vscode.commands.registerCommand('devchat.askForFile', async () => {
|
||||||
|
const editor = vscode.window.activeTextEditor;
|
||||||
|
if (editor) {
|
||||||
|
if (!ensureChatPanel(context)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await sendFileSelectMessage(ChatPanel.currentPanel()!.panel(), editor.document.fileName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
context.subscriptions.push(disposableAskFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
registerOpenChatPanelCommand,
|
||||||
|
registerAddContextCommand,
|
||||||
|
registerAskForCodeCommand,
|
||||||
|
registerAskForFileCommand,
|
||||||
|
};
|
14
src/contributes/util.ts
Normal file
14
src/contributes/util.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
import { handleCodeSelected } from '../context/contextCodeSelected';
|
||||||
|
import { handleFileSelected } from '../context/contextFileSelected';
|
||||||
|
|
||||||
|
export async function sendFileSelectMessage(panel: vscode.WebviewPanel, filePath: string): Promise<void> {
|
||||||
|
const codeContext = await handleFileSelected(filePath);
|
||||||
|
panel.webview.postMessage({ command: 'appendContext', context: codeContext });
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendCodeSelectMessage(panel: vscode.WebviewPanel, filePath: string, codeBlock: string): Promise<void> {
|
||||||
|
const codeContext = await handleCodeSelected(filePath, codeBlock);
|
||||||
|
panel.webview.postMessage({ command: 'appendContext', context: codeContext });
|
||||||
|
}
|
106
src/extension.ts
106
src/extension.ts
@ -1,42 +1,15 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as ncp from 'ncp'; // 需要安装 ncp 模块,用于复制目录
|
|
||||||
|
|
||||||
const ChatPanel = require('./chatPanel').default;
|
import { createChatDirectoryAndCopyInstructionsSync } from './init/chatConfig';
|
||||||
const sendFileSelectMessage = require('./messageHandler').sendFileSelectMessage;
|
import {
|
||||||
const sendCodeSelectMessage = require('./messageHandler').sendCodeSelectMessage;
|
registerOpenChatPanelCommand,
|
||||||
import ExtensionContextHolder from './extensionContext';
|
registerAddContextCommand,
|
||||||
|
registerAskForCodeCommand,
|
||||||
|
registerAskForFileCommand,
|
||||||
|
} from './contributes/commands';
|
||||||
|
|
||||||
function createChatDirectoryAndCopyInstructionsSync(extensionUri: vscode.Uri) {
|
import ExtensionContextHolder from './util/extensionContext';
|
||||||
|
|
||||||
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
||||||
if (!workspaceFolders) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const workspaceRoot = workspaceFolders[0].uri.fsPath;
|
|
||||||
const chatDirPath = path.join(workspaceRoot, '.chat');
|
|
||||||
const instructionsSrcPath = path.join(extensionUri.fsPath, 'instructions');
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 检查 .chat 目录是否存在,如果不存在,则创建它
|
|
||||||
if (!fs.existsSync(chatDirPath)) {
|
|
||||||
fs.mkdirSync(chatDirPath);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将 instructions 目录复制到 .chat 目录中
|
|
||||||
ncp.ncp(instructionsSrcPath, path.join(chatDirPath, 'instructions'), (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error copying instructions:', err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating .chat directory and copying instructions:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function activate(context: vscode.ExtensionContext) {
|
function activate(context: vscode.ExtensionContext) {
|
||||||
ExtensionContextHolder.context = context;
|
ExtensionContextHolder.context = context;
|
||||||
@ -44,64 +17,9 @@ function activate(context: vscode.ExtensionContext) {
|
|||||||
// 创建 .chat 目录并复制 instructions
|
// 创建 .chat 目录并复制 instructions
|
||||||
createChatDirectoryAndCopyInstructionsSync(context.extensionUri);
|
createChatDirectoryAndCopyInstructionsSync(context.extensionUri);
|
||||||
|
|
||||||
let disposable = vscode.commands.registerCommand('devchat.openChatPanel', () => {
|
registerOpenChatPanelCommand(context);
|
||||||
if (vscode.workspace.workspaceFolders) {
|
registerAddContextCommand(context);
|
||||||
ChatPanel.createOrShow(context.extensionUri);
|
registerAskForCodeCommand(context);
|
||||||
} else {
|
registerAskForFileCommand(context);
|
||||||
vscode.window.showErrorMessage('Please open a directory before using the chat panel.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const disposable_add_context = vscode.commands.registerCommand('devchat.addConext', async (uri: { path: any; }) => {
|
|
||||||
if (!ChatPanel.currentPanel()) {
|
|
||||||
if (vscode.workspace.workspaceFolders) {
|
|
||||||
ChatPanel.createOrShow(context.extensionUri);
|
|
||||||
} else {
|
|
||||||
vscode.window.showErrorMessage('Please open a directory before using the chat panel.');
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await sendFileSelectMessage(ChatPanel.currentPanel().panel(), uri.path);
|
|
||||||
});
|
|
||||||
|
|
||||||
const disposableCodeContext = vscode.commands.registerCommand('devchat.askForCode', async () => {
|
|
||||||
const editor = vscode.window.activeTextEditor;
|
|
||||||
if (editor) {
|
|
||||||
if (!ChatPanel.currentPanel()) {
|
|
||||||
if (vscode.workspace.workspaceFolders) {
|
|
||||||
ChatPanel.createOrShow(context.extensionUri);
|
|
||||||
} else {
|
|
||||||
vscode.window.showErrorMessage('Please open a directory before using the chat panel.');
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedText = editor.document.getText(editor.selection);
|
|
||||||
await sendCodeSelectMessage(ChatPanel.currentPanel().panel(), editor.document.fileName, selectedText);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const disposableAskFile = vscode.commands.registerCommand('devchat.askForFile', async () => {
|
|
||||||
const editor = vscode.window.activeTextEditor;
|
|
||||||
if (editor) {
|
|
||||||
if (!ChatPanel.currentPanel()) {
|
|
||||||
if (vscode.workspace.workspaceFolders) {
|
|
||||||
ChatPanel.createOrShow(context.extensionUri);
|
|
||||||
} else {
|
|
||||||
vscode.window.showErrorMessage('Please open a directory before using the chat panel.');
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectedText = editor.document.getText();
|
|
||||||
sendCodeSelectMessage(ChatPanel.currentPanel().panel(), selectedText);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
context.subscriptions.push(disposable);
|
|
||||||
context.subscriptions.push(disposable_add_context);
|
|
||||||
context.subscriptions.push(disposableCodeContext)
|
|
||||||
context.subscriptions.push(disposableAskFile)
|
|
||||||
}
|
}
|
||||||
exports.activate = activate;
|
exports.activate = activate;
|
||||||
|
12
src/handler/addContext.ts
Normal file
12
src/handler/addContext.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import ChatContextManager from '../context/contextManager';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
|
|
||||||
|
async function addConext(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const contextStr = await ChatContextManager.getInstance().processText(message.selected);
|
||||||
|
panel.webview.postMessage({ command: 'appendContext', context: contextStr });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('addContext', addConext);
|
||||||
|
|
32
src/handler/codeApply.ts
Normal file
32
src/handler/codeApply.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { messageHandler } from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
export async function applyCode(text: string) {
|
||||||
|
if (vscode.window.visibleTextEditors.length > 1) {
|
||||||
|
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const editor = vscode.window.visibleTextEditors[0];
|
||||||
|
if (!editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selection = editor.selection;
|
||||||
|
const start = selection.start;
|
||||||
|
const end = selection.end;
|
||||||
|
|
||||||
|
await editor.edit((editBuilder: vscode.TextEditorEdit) => {
|
||||||
|
editBuilder.replace(new vscode.Range(start, end), text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function codeApply(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
await applyCode(message.content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('code_apply', codeApply);
|
||||||
|
|
33
src/handler/codeFileApply.ts
Normal file
33
src/handler/codeFileApply.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import { messageHandler } from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function applyCodeFile(text: string) {
|
||||||
|
if (vscode.window.visibleTextEditors.length > 1) {
|
||||||
|
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const editor = vscode.window.visibleTextEditors[0];
|
||||||
|
if (!editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const document = editor.document;
|
||||||
|
const fullRange = new vscode.Range(
|
||||||
|
document.positionAt(0),
|
||||||
|
document.positionAt(document.getText().length)
|
||||||
|
);
|
||||||
|
|
||||||
|
await editor.edit((editBuilder: vscode.TextEditorEdit) => {
|
||||||
|
editBuilder.replace(fullRange, text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function codeFileApply(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
await applyCodeFile(message.content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('code_file_apply', codeFileApply);
|
12
src/handler/convertCommand.ts
Normal file
12
src/handler/convertCommand.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import CommandManager from '../command/commandManager';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
async function convertCommand(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const newText = await CommandManager.getInstance().processText(message.text);
|
||||||
|
panel.webview.postMessage({ command: 'convertCommand', result: newText });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('convertCommand', convertCommand);
|
19
src/handler/doCommit.ts
Normal file
19
src/handler/doCommit.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import DtmWrapper from '../toolwrapper/dtm';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
async function doCommit(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const dtmWrapper = new DtmWrapper();
|
||||||
|
|
||||||
|
const commitResult = await dtmWrapper.commit(message.content);
|
||||||
|
if (commitResult.status === 0) {
|
||||||
|
vscode.window.showInformationMessage('Commit successfully.');
|
||||||
|
} else {
|
||||||
|
vscode.window.showErrorMessage(`Error commit fail: ${commitResult.message} ${commitResult.log}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('doCommit', doCommit);
|
||||||
|
|
16
src/handler/historyMessages.ts
Normal file
16
src/handler/historyMessages.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import DevChat, { LogOptions } from '../toolwrapper/devchat';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
async function historyMessages(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const devChat = new DevChat();
|
||||||
|
|
||||||
|
const logOptions: LogOptions = message.options || {};
|
||||||
|
const logEntries = await devChat.log(logOptions);
|
||||||
|
panel.webview.postMessage({ command: 'loadHistoryMessages', entries: logEntries });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('historyMessages', historyMessages);
|
||||||
|
|
10
src/handler/loadHandlers.ts
Normal file
10
src/handler/loadHandlers.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import './addContext';
|
||||||
|
import './codeApply';
|
||||||
|
import './codeFileApply';
|
||||||
|
import './convertCommand';
|
||||||
|
import './doCommit';
|
||||||
|
import './historyMessages';
|
||||||
|
import './regCommandList';
|
||||||
|
import './regContextList';
|
||||||
|
import './sendMessage';
|
||||||
|
import './showDiff';
|
34
src/handler/messageHandler.ts
Normal file
34
src/handler/messageHandler.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// messageHandler.ts
|
||||||
|
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
import '../command/loadCommands';
|
||||||
|
import '../context/loadContexts'
|
||||||
|
|
||||||
|
|
||||||
|
class MessageHandler {
|
||||||
|
private handlers: { [command: string]: (message: any, panel: vscode.WebviewPanel) => Promise<void> } = {};
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
registerHandler(command: string, handler: (message: any, panel: vscode.WebviewPanel) => Promise<void>): void {
|
||||||
|
this.handlers[command] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleMessage(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const handler = this.handlers[message.command];
|
||||||
|
if (handler) {
|
||||||
|
await handler(message, panel);
|
||||||
|
} else {
|
||||||
|
console.error(`No handler found for command "${message.command}"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage(panel: vscode.WebviewPanel, command: string, data: any): void {
|
||||||
|
panel.webview.postMessage({ command, ...data });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const messageHandler = new MessageHandler();
|
||||||
|
export default messageHandler.handleMessage.bind(messageHandler);
|
13
src/handler/regCommandList.ts
Normal file
13
src/handler/regCommandList.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import CommandManager from '../command/commandManager';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
async function regCommandList(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const commandList = CommandManager.getInstance().getCommandList();
|
||||||
|
panel.webview.postMessage({ command: 'regCommandList', result: commandList });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('regCommandList', regCommandList);
|
||||||
|
|
12
src/handler/regContextList.ts
Normal file
12
src/handler/regContextList.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import ChatContextManager from '../context/contextManager';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
async function regContextList(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const contextList = ChatContextManager.getInstance().getContextList();
|
||||||
|
panel.webview.postMessage({ command: 'regContextList', result: contextList });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('regContextList', regContextList);
|
108
src/handler/sendMessage.ts
Normal file
108
src/handler/sendMessage.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import DevChat from '../toolwrapper/devchat';
|
||||||
|
import CommandManager from '../command/commandManager';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
|
|
||||||
|
|
||||||
|
// Add this function to messageHandler.ts
|
||||||
|
function parseMessage(message: string): { context: string[]; instruction: string[]; reference: string[]; text: string } {
|
||||||
|
const contextRegex = /\[context\|(.*?)\]/g;
|
||||||
|
const instructionRegex = /\[instruction\|(.*?)\]/g;
|
||||||
|
const referenceRegex = /\[reference\|(.*?)\]/g;
|
||||||
|
|
||||||
|
const contextPaths = [];
|
||||||
|
const instructionPaths = [];
|
||||||
|
const referencePaths = [];
|
||||||
|
|
||||||
|
let match;
|
||||||
|
|
||||||
|
// 提取 context
|
||||||
|
while ((match = contextRegex.exec(message)) !== null) {
|
||||||
|
contextPaths.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取 instruction
|
||||||
|
while ((match = instructionRegex.exec(message)) !== null) {
|
||||||
|
instructionPaths.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取 reference
|
||||||
|
while ((match = referenceRegex.exec(message)) !== null) {
|
||||||
|
referencePaths.push(match[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除标签,保留纯文本
|
||||||
|
const text = message
|
||||||
|
.replace(contextRegex, '')
|
||||||
|
.replace(instructionRegex, '')
|
||||||
|
.replace(referenceRegex, '')
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
return { context: contextPaths, instruction: instructionPaths, reference: referencePaths, text };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInstructionFiles(): string[] {
|
||||||
|
const instructionFiles: string[] = [];
|
||||||
|
const workspaceDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
||||||
|
if (workspaceDir) {
|
||||||
|
const chatInstructionsPath = path.join(workspaceDir, '.chat', 'instructions', 'default');
|
||||||
|
try {
|
||||||
|
// 读取 chatInstructionsPath 目录下的所有文件和目录
|
||||||
|
const files = fs.readdirSync(chatInstructionsPath);
|
||||||
|
// 过滤出文件,忽略目录
|
||||||
|
for (const file of files) {
|
||||||
|
const filePath = path.join(chatInstructionsPath, file);
|
||||||
|
const fileStats = fs.statSync(filePath);
|
||||||
|
if (fileStats.isFile()) {
|
||||||
|
instructionFiles.push(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading instruction files:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return instructionFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastPromptHash: string | undefined;
|
||||||
|
|
||||||
|
async function sendMessage(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
const devChat = new DevChat();
|
||||||
|
|
||||||
|
const newText2 = await CommandManager.getInstance().processText(message.text);
|
||||||
|
panel.webview.postMessage({ command: 'convertCommand', result: newText2 });
|
||||||
|
|
||||||
|
const parsedMessage = parseMessage(newText2);
|
||||||
|
const chatOptions: any = lastPromptHash ? { parent: lastPromptHash } : {};
|
||||||
|
|
||||||
|
if (parsedMessage.context.length > 0) {
|
||||||
|
chatOptions.context = parsedMessage.context;
|
||||||
|
}
|
||||||
|
|
||||||
|
chatOptions.header = getInstructionFiles();
|
||||||
|
if (parsedMessage.instruction.length > 0) {
|
||||||
|
chatOptions.header = parsedMessage.instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsedMessage.reference.length > 0) {
|
||||||
|
chatOptions.reference = parsedMessage.reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
let partialData = "";
|
||||||
|
const onData = (partialResponse: string) => {
|
||||||
|
partialData += partialResponse;
|
||||||
|
panel.webview.postMessage({ command: 'receiveMessagePartial', text: partialData });
|
||||||
|
};
|
||||||
|
|
||||||
|
const chatResponse = await devChat.chat(parsedMessage.text, chatOptions, onData);
|
||||||
|
lastPromptHash = chatResponse["prompt-hash"];
|
||||||
|
const response = chatResponse.response;
|
||||||
|
panel.webview.postMessage({ command: 'receiveMessage', text: response });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('sendMessage', sendMessage);
|
||||||
|
|
@ -1,50 +1,9 @@
|
|||||||
const vscode = require('vscode');
|
import * as vscode from 'vscode';
|
||||||
|
import {messageHandler} from './messageHandler';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { createTempSubdirectory } from './commonUtil';
|
import { createTempSubdirectory } from '../util/commonUtil';
|
||||||
|
|
||||||
|
|
||||||
export async function applyCodeFile(text: string) {
|
|
||||||
if (vscode.window.visibleTextEditors.length > 1) {
|
|
||||||
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const editor = vscode.window.visibleTextEditors[0];
|
|
||||||
if (!editor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const document = editor.document;
|
|
||||||
const fullRange = new vscode.Range(
|
|
||||||
document.positionAt(0),
|
|
||||||
document.positionAt(document.getText().length)
|
|
||||||
);
|
|
||||||
|
|
||||||
await editor.edit((editBuilder: string) => {
|
|
||||||
editBuilder.replace(fullRange, text);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function applyCode(text: string) {
|
|
||||||
if (vscode.window.visibleTextEditors.length > 1) {
|
|
||||||
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const editor = vscode.window.visibleTextEditors[0];
|
|
||||||
if (!editor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const selection = editor.selection;
|
|
||||||
const start = selection.start;
|
|
||||||
const end = selection.end;
|
|
||||||
|
|
||||||
await editor.edit((editBuilder: string) => {
|
|
||||||
editBuilder.replace(new vscode.Range(start, end), text);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function diffView(code: string) {
|
export async function diffView(code: string) {
|
||||||
if (vscode.window.visibleTextEditors.length > 1) {
|
if (vscode.window.visibleTextEditors.length > 1) {
|
||||||
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
vscode.window.showErrorMessage(`There are more then one visible text editors. Please close all but one and try again.`);
|
||||||
@ -85,3 +44,17 @@ export async function diffView(code: string) {
|
|||||||
vscode.commands.executeCommand('vscode.diff', vscode.Uri.file(curFile), vscode.Uri.file(tempFile), 'Diff View');
|
vscode.commands.executeCommand('vscode.diff', vscode.Uri.file(curFile), vscode.Uri.file(tempFile), 'Diff View');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function showDiff(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
diffView(message.content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function blockApply(message: any, panel: vscode.WebviewPanel): Promise<void> {
|
||||||
|
diffView(message.content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler.registerHandler('block_apply', blockApply);
|
||||||
|
messageHandler.registerHandler('show_diff', showDiff);
|
34
src/init/chatConfig.ts
Normal file
34
src/init/chatConfig.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as ncp from 'ncp';
|
||||||
|
|
||||||
|
export function createChatDirectoryAndCopyInstructionsSync(extensionUri: vscode.Uri) {
|
||||||
|
|
||||||
|
const workspaceFolders = vscode.workspace.workspaceFolders;
|
||||||
|
if (!workspaceFolders) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workspaceRoot = workspaceFolders[0].uri.fsPath;
|
||||||
|
const chatDirPath = path.join(workspaceRoot, '.chat');
|
||||||
|
const instructionsSrcPath = path.join(extensionUri.fsPath, 'instructions');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 检查 .chat 目录是否存在,如果不存在,则创建它
|
||||||
|
if (!fs.existsSync(chatDirPath)) {
|
||||||
|
fs.mkdirSync(chatDirPath);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 instructions 目录复制到 .chat 目录中
|
||||||
|
ncp.ncp(instructionsSrcPath, path.join(chatDirPath, 'instructions'), (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('Error copying instructions:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error creating .chat directory and copying instructions:', error);
|
||||||
|
}
|
||||||
|
}
|
@ -1,193 +0,0 @@
|
|||||||
// messageHandler.ts
|
|
||||||
|
|
||||||
import * as vscode from 'vscode';
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import { promisify } from 'util';
|
|
||||||
import DevChat, { LogOptions } from './devchat';
|
|
||||||
import DtmWrapper from './dtm';
|
|
||||||
import {applyCodeFile, diffView, applyCode} from './applyCode';
|
|
||||||
|
|
||||||
import './loadCommands';
|
|
||||||
import './loadContexts'
|
|
||||||
import CommandManager, { Command } from './commandManager';
|
|
||||||
import ChatContextManager from './contextManager';
|
|
||||||
import { handleCodeSelected } from './contextCodeSelected';
|
|
||||||
import { handleFileSelected } from './contextFileSelected';
|
|
||||||
|
|
||||||
import * as vscode3 from 'vscode';
|
|
||||||
|
|
||||||
const writeFileAsync = promisify(fs.writeFile);
|
|
||||||
const unlinkAsync = promisify(fs.unlink);
|
|
||||||
|
|
||||||
let lastPromptHash: string | undefined;
|
|
||||||
|
|
||||||
async function saveTempPatchFile(content: string): Promise<string> {
|
|
||||||
const tempPatchFilePath = path.join(vscode.workspace.workspaceFolders![0].uri.fsPath, '.temp_patch_file.patch');
|
|
||||||
await writeFileAsync(tempPatchFilePath, content);
|
|
||||||
return tempPatchFilePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteTempPatchFile(filePath: string): Promise<void> {
|
|
||||||
await unlinkAsync(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function sendFileSelectMessage(panel: vscode.WebviewPanel, filePath: string): Promise<void> {
|
|
||||||
const codeContext = await handleFileSelected(filePath);
|
|
||||||
panel.webview.postMessage({ command: 'appendContext', context: codeContext });
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function sendCodeSelectMessage(panel: vscode.WebviewPanel, filePath: string, codeBlock: string): Promise<void> {
|
|
||||||
const codeContext = await handleCodeSelected(filePath, codeBlock);
|
|
||||||
panel.webview.postMessage({ command: 'appendContext', context: codeContext });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function askAI(panel: vscode.WebviewPanel, codeBlock: string, question: string): void {
|
|
||||||
panel.webview.postMessage({ command: 'ask_ai', codeBlock, question });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this function to messageHandler.ts
|
|
||||||
function parseMessage(message: string): { context: string[]; instruction: string[]; reference: string[]; text: string } {
|
|
||||||
const contextRegex = /\[context\|(.*?)\]/g;
|
|
||||||
const instructionRegex = /\[instruction\|(.*?)\]/g;
|
|
||||||
const referenceRegex = /\[reference\|(.*?)\]/g;
|
|
||||||
|
|
||||||
const contextPaths = [];
|
|
||||||
const instructionPaths = [];
|
|
||||||
const referencePaths = [];
|
|
||||||
|
|
||||||
let match;
|
|
||||||
|
|
||||||
// 提取 context
|
|
||||||
while ((match = contextRegex.exec(message)) !== null) {
|
|
||||||
contextPaths.push(match[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提取 instruction
|
|
||||||
while ((match = instructionRegex.exec(message)) !== null) {
|
|
||||||
instructionPaths.push(match[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提取 reference
|
|
||||||
while ((match = referenceRegex.exec(message)) !== null) {
|
|
||||||
referencePaths.push(match[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除标签,保留纯文本
|
|
||||||
const text = message
|
|
||||||
.replace(contextRegex, '')
|
|
||||||
.replace(instructionRegex, '')
|
|
||||||
.replace(referenceRegex, '')
|
|
||||||
.trim();
|
|
||||||
|
|
||||||
return { context: contextPaths, instruction: instructionPaths, reference: referencePaths, text };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getInstructionFiles(): string[] {
|
|
||||||
const instructionFiles: string[] = [];
|
|
||||||
const workspaceDir = vscode.workspace.workspaceFolders?.[0].uri.fsPath;
|
|
||||||
if (workspaceDir) {
|
|
||||||
const chatInstructionsPath = path.join(workspaceDir, '.chat', 'instructions', 'default');
|
|
||||||
try {
|
|
||||||
// 读取 chatInstructionsPath 目录下的所有文件和目录
|
|
||||||
const files = fs.readdirSync(chatInstructionsPath);
|
|
||||||
// 过滤出文件,忽略目录
|
|
||||||
for (const file of files) {
|
|
||||||
const filePath = path.join(chatInstructionsPath, file);
|
|
||||||
const fileStats = fs.statSync(filePath);
|
|
||||||
if (fileStats.isFile()) {
|
|
||||||
instructionFiles.push(filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error reading instruction files:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return instructionFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleMessage(
|
|
||||||
message: any,
|
|
||||||
panel: vscode.WebviewPanel
|
|
||||||
): Promise<void> {
|
|
||||||
const devChat = new DevChat();
|
|
||||||
const dtmWrapper = new DtmWrapper();
|
|
||||||
|
|
||||||
switch (message.command) {
|
|
||||||
case 'sendMessage':
|
|
||||||
const newText2 = await CommandManager.getInstance().processText(message.text);
|
|
||||||
panel.webview.postMessage({ command: 'convertCommand', result: newText2 });
|
|
||||||
|
|
||||||
const parsedMessage = parseMessage(newText2);
|
|
||||||
const chatOptions: any = lastPromptHash ? { parent: lastPromptHash } : {};
|
|
||||||
|
|
||||||
if (parsedMessage.context.length > 0) {
|
|
||||||
chatOptions.context = parsedMessage.context;
|
|
||||||
}
|
|
||||||
|
|
||||||
chatOptions.header = getInstructionFiles();
|
|
||||||
if (parsedMessage.instruction.length > 0) {
|
|
||||||
chatOptions.header = parsedMessage.instruction;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parsedMessage.reference.length > 0) {
|
|
||||||
chatOptions.reference = parsedMessage.reference;
|
|
||||||
}
|
|
||||||
|
|
||||||
let partialData = "";
|
|
||||||
const onData = (partialResponse: string) => {
|
|
||||||
partialData += partialResponse;
|
|
||||||
panel.webview.postMessage({ command: 'receiveMessagePartial', text: partialData });
|
|
||||||
};
|
|
||||||
|
|
||||||
const chatResponse = await devChat.chat(parsedMessage.text, chatOptions, onData);
|
|
||||||
lastPromptHash = chatResponse["prompt-hash"];
|
|
||||||
const response = chatResponse.response;
|
|
||||||
panel.webview.postMessage({ command: 'receiveMessage', text: response });
|
|
||||||
return;
|
|
||||||
case 'historyMessages':
|
|
||||||
const logOptions: LogOptions = message.options || {};
|
|
||||||
const logEntries = await devChat.log(logOptions);
|
|
||||||
panel.webview.postMessage({ command: 'loadHistoryMessages', entries: logEntries });
|
|
||||||
return;
|
|
||||||
case 'show_diff':
|
|
||||||
diffView(message.content);
|
|
||||||
return;
|
|
||||||
// TODO: remove block_apply
|
|
||||||
case 'block_apply':
|
|
||||||
diffView(message.content);
|
|
||||||
return;
|
|
||||||
case 'code_apply':
|
|
||||||
await applyCode(message.content);
|
|
||||||
return;
|
|
||||||
case 'code_file_apply':
|
|
||||||
await applyCodeFile(message.content);
|
|
||||||
return;
|
|
||||||
case 'regCommandList':
|
|
||||||
const commandList = CommandManager.getInstance().getCommandList();
|
|
||||||
panel.webview.postMessage({ command: 'regCommandList', result: commandList });
|
|
||||||
return;
|
|
||||||
case 'convertCommand':
|
|
||||||
const newText = await CommandManager.getInstance().processText(message.text);
|
|
||||||
panel.webview.postMessage({ command: 'convertCommand', result: newText });
|
|
||||||
return;
|
|
||||||
case 'doCommit':
|
|
||||||
const commitResult = await dtmWrapper.commit(message.content);
|
|
||||||
if (commitResult.status === 0) {
|
|
||||||
vscode.window.showInformationMessage('Commit successfully.');
|
|
||||||
} else {
|
|
||||||
vscode.window.showErrorMessage(`Error commit fail: ${commitResult.message} ${commitResult.log}`);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case 'regContextList':
|
|
||||||
const contextList = ChatContextManager.getInstance().getContextList();
|
|
||||||
panel.webview.postMessage({ command: 'regContextList', result: contextList });
|
|
||||||
return;
|
|
||||||
case 'addContext':
|
|
||||||
const contextStr = await ChatContextManager.getInstance().processText(message.selected);
|
|
||||||
panel.webview.postMessage({ command: 'appendContext', context: contextStr });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default handleMessage;
|
|
79
src/panel/chatPanel.ts
Normal file
79
src/panel/chatPanel.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// chatPanel.ts
|
||||||
|
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import '../handler/loadHandlers';
|
||||||
|
import handleMessage from '../handler/messageHandler';
|
||||||
|
import WebviewManager from './webviewManager';
|
||||||
|
|
||||||
|
export default class ChatPanel {
|
||||||
|
private static _instance: ChatPanel | undefined;
|
||||||
|
private readonly _panel: vscode.WebviewPanel;
|
||||||
|
private _webviewManager: WebviewManager;
|
||||||
|
private _disposables: vscode.Disposable[] = [];
|
||||||
|
|
||||||
|
public static createOrShow(extensionUri: vscode.Uri) {
|
||||||
|
if (ChatPanel._instance) {
|
||||||
|
ChatPanel._instance._panel.reveal();
|
||||||
|
} else {
|
||||||
|
const panel = ChatPanel.createWebviewPanel(extensionUri);
|
||||||
|
ChatPanel._instance = new ChatPanel(panel, extensionUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static currentPanel(): ChatPanel | undefined {
|
||||||
|
return ChatPanel._instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new webview panel
|
||||||
|
private static createWebviewPanel(extensionUri: vscode.Uri): vscode.WebviewPanel {
|
||||||
|
const column = vscode.window.activeTextEditor
|
||||||
|
? vscode.window.activeTextEditor.viewColumn
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return vscode.window.createWebviewPanel(
|
||||||
|
'chatPanel',
|
||||||
|
'Chat',
|
||||||
|
column || vscode.ViewColumn.One,
|
||||||
|
{
|
||||||
|
enableScripts: true,
|
||||||
|
localResourceRoots: [vscode.Uri.joinPath(extensionUri, 'dist')],
|
||||||
|
retainContextWhenHidden: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
|
||||||
|
this._panel = panel;
|
||||||
|
this._webviewManager = new WebviewManager(panel.webview, extensionUri);
|
||||||
|
this.registerEventListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public panel(): vscode.WebviewPanel {
|
||||||
|
return this._panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register event listeners for the panel and webview
|
||||||
|
private registerEventListeners() {
|
||||||
|
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
|
||||||
|
|
||||||
|
this._panel.webview.onDidReceiveMessage(
|
||||||
|
async (message) => {
|
||||||
|
handleMessage(message, this._panel);
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
this._disposables
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispose the panel and clean up resources
|
||||||
|
public dispose() {
|
||||||
|
ChatPanel._instance = undefined;
|
||||||
|
this._panel.dispose();
|
||||||
|
while (this._disposables.length) {
|
||||||
|
const disposable = this._disposables.pop();
|
||||||
|
if (disposable) {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
src/panel/webviewManager.ts
Normal file
36
src/panel/webviewManager.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
export default class WebviewManager {
|
||||||
|
private _webview: vscode.Webview;
|
||||||
|
private _extensionUri: vscode.Uri;
|
||||||
|
|
||||||
|
constructor(webview: vscode.Webview, extensionUri: vscode.Uri) {
|
||||||
|
this._webview = webview;
|
||||||
|
this._extensionUri = extensionUri;
|
||||||
|
this.setWebviewOptions();
|
||||||
|
this.setWebviewContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private setWebviewOptions() {
|
||||||
|
this._webview.options = {
|
||||||
|
enableScripts: true,
|
||||||
|
localResourceRoots: [vscode.Uri.joinPath(this._extensionUri, 'dist')],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private setWebviewContent() {
|
||||||
|
this._webview.html = this._getHtmlContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getHtmlContent(): string {
|
||||||
|
const htmlPath = vscode.Uri.joinPath(this._extensionUri, 'dist', 'assets', 'chatPanel.html');
|
||||||
|
const htmlContent = fs.readFileSync(htmlPath.fsPath, 'utf8');
|
||||||
|
|
||||||
|
return htmlContent.replace(/<vscode-resource:(\/.+?)>/g, (_, resourcePath) => {
|
||||||
|
const resourceUri = vscode.Uri.joinPath(this._extensionUri, 'dist', resourcePath);
|
||||||
|
return this._webview.asWebviewUri(resourceUri).toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user