From e6d5e410fc5c8d63aeb5ae2ff08daa0b5b8642ca Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 01/25] remove pre-release flag --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ea44aa..0a4c6b0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,7 +25,7 @@ jobs: sed -i "s/\"version\": \".*\",/\"version\": \"${CIRCLE_TAG:1}\",/" package.json - run: name: "Publish to Marketplace" - command: npx vsce publish -p $VSCE_TOKEN --allow-star-activation --pre-release + command: npx vsce publish -p $VSCE_TOKEN --allow-star-activation workflows: version: 2 build-and-publish: From 950a1328a061ca966695718bb21faba71c3da3c7 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 02/25] Add language tag component - Create LanguageCorner component to display language tag - Update MessageMarkdown to render LanguageCorner - Pass language prop from Message to LanguageCorner --- .../MessageMarkdown/LanguageCorner.tsx | 24 +++++++++++++++++++ .../components/MessageMarkdown/index.tsx | 21 ++-------------- 2 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 src/views/components/MessageMarkdown/LanguageCorner.tsx diff --git a/src/views/components/MessageMarkdown/LanguageCorner.tsx b/src/views/components/MessageMarkdown/LanguageCorner.tsx new file mode 100644 index 0000000..10d12b4 --- /dev/null +++ b/src/views/components/MessageMarkdown/LanguageCorner.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +interface LanguageCornerProps { + language: string; +} +const LanguageCorner: React.FC = ({ language }) => { + return ( +
+ {language && ( +
+ {language} +
+ )} +
+ ); +}; + +export default LanguageCorner; \ No newline at end of file diff --git a/src/views/components/MessageMarkdown/index.tsx b/src/views/components/MessageMarkdown/index.tsx index 93c9b8f..79e9d8e 100644 --- a/src/views/components/MessageMarkdown/index.tsx +++ b/src/views/components/MessageMarkdown/index.tsx @@ -1,10 +1,11 @@ -import { Button, Anchor } from "@mantine/core"; +import { Button, Anchor, Stack, Group, Box } from "@mantine/core"; import React from "react"; import ReactMarkdown from "react-markdown"; import rehypeRaw from "rehype-raw"; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism"; import CodeButtons from "./CodeButtons"; +import LanguageCorner from "./LanguageCorner"; import { observer } from "mobx-react-lite"; import { useMst } from "@/views/stores/RootStore"; import { Message } from "@/views/stores/ChatStore"; @@ -19,24 +20,6 @@ const MessageMarkdown = observer((props: MessageMarkdownProps) => { const { children } = props; const { chat } = useMst(); - const LanguageCorner = (props: any) => { - const { language } = props; - - return (
- {language && ( -
- {language} -
- )} -
); - }; - const handleExplain = (value: string | undefined) => { console.log(value); switch (value) { From 3afd42c9d622b07b18d2d526c9ea42f79058d6c0 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 03/25] Add collapsible code step component - Create Step component to wrap code snippets in collapsible box - Render Step instead of default code block for 'step' language - Pass code snippet as children prop to Step - Step renders language tag and toggle button --- src/views/components/MessageMarkdown/Step.tsx | 38 +++++++++++++++++++ .../components/MessageMarkdown/index.tsx | 6 +++ 2 files changed, 44 insertions(+) create mode 100644 src/views/components/MessageMarkdown/Step.tsx diff --git a/src/views/components/MessageMarkdown/Step.tsx b/src/views/components/MessageMarkdown/Step.tsx new file mode 100644 index 0000000..b3df0c0 --- /dev/null +++ b/src/views/components/MessageMarkdown/Step.tsx @@ -0,0 +1,38 @@ +import { Box, Button, Collapse, Group } from "@mantine/core"; +import { useDisclosure } from "@mantine/hooks"; +import React from "react"; +import SyntaxHighlighter from "react-syntax-highlighter"; +import LanguageCorner from "./LanguageCorner"; +import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism"; + +interface StepProps { + language: string; + children: string; + } +const Step: React.FC = (props) => { + const {language,children} = props; + const [opened, { toggle }] = useDisclosure(false); + + return ( + + + + + + +
+ + + {children} + +
+
+
+ ); + }; + + export default Step; \ No newline at end of file diff --git a/src/views/components/MessageMarkdown/index.tsx b/src/views/components/MessageMarkdown/index.tsx index 79e9d8e..411c62d 100644 --- a/src/views/components/MessageMarkdown/index.tsx +++ b/src/views/components/MessageMarkdown/index.tsx @@ -5,6 +5,7 @@ import rehypeRaw from "rehype-raw"; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism"; import CodeButtons from "./CodeButtons"; +import Step from "./Step"; import LanguageCorner from "./LanguageCorner"; import { observer } from "mobx-react-lite"; import { useMst } from "@/views/stores/RootStore"; @@ -133,6 +134,11 @@ Generate a professionally written and formatted release note in markdown with th if (lanugage === 'markdown' || lanugage === 'text') { wrapLongLines = true; } + + if (lanugage === 'step') { + return {value}; + } + return !inline && lanugage ? (
From 960b0294bc4842480f4b3e9cabc97f419a467a1a Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 04/25] Add collapsible section for each step - Add Accordion component from Mantine to wrap each step content - Extract first line starting with '#' as section title - Show chevron icon when section is collapsed - Show check icon when code block is expanded - Style Accordion to match VSCode theme - Remove original toggle button and collapse component --- src/views/components/MessageMarkdown/Step.tsx | 114 ++++++++++++++---- 1 file changed, 92 insertions(+), 22 deletions(-) diff --git a/src/views/components/MessageMarkdown/Step.tsx b/src/views/components/MessageMarkdown/Step.tsx index b3df0c0..ef241aa 100644 --- a/src/views/components/MessageMarkdown/Step.tsx +++ b/src/views/components/MessageMarkdown/Step.tsx @@ -1,38 +1,108 @@ -import { Box, Button, Collapse, Group } from "@mantine/core"; +import { Accordion, Box, Button, Collapse, Group,Loader,Text } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; import React from "react"; import SyntaxHighlighter from "react-syntax-highlighter"; import LanguageCorner from "./LanguageCorner"; import { okaidia } from "react-syntax-highlighter/dist/esm/styles/prism"; +import { IconCheck, IconChevronDown, IconFileDiff, IconLoader } from "@tabler/icons-react"; +import { observer } from "mobx-react-lite"; +import { useMst } from "@/views/stores/RootStore"; +import { keyframes,css } from "@emotion/react"; interface StepProps { language: string; + closed:boolean; children: string; - } -const Step: React.FC = (props) => { - const {language,children} = props; - const [opened, { toggle }] = useDisclosure(false); - - return ( - - - - - - -
- +} + +const Step: React.FC = observer((props) => { + const { chat } = useMst(); + const {language,closed,children} = props; + const [opened, { toggle }] = useDisclosure(false); + + // extract first line with # as button label + const lines = children.split('\n'); + const title = lines.length>0&&lines[0].indexOf('#')>=0?lines[0].split('#')[1]:''; + + + const spin = keyframes` + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + `; + + return <> + {lines.length > 1 && + + + : + } + > + {title} + + {children} -
-
-
- ); - }; + + + } + ; + }); export default Step; \ No newline at end of file From b35ee9ef8c7df14d0dae9b2b2457b34b4378e485 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 05/25] Display check icon for completed step - Check if last line is '# Done' to determine step completion - Extract step contents, omitting first and last line - Show check icon if step is completed, else show loader - Remove closed prop which is no longer needed --- src/views/components/MessageMarkdown/Step.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/views/components/MessageMarkdown/Step.tsx b/src/views/components/MessageMarkdown/Step.tsx index ef241aa..905757f 100644 --- a/src/views/components/MessageMarkdown/Step.tsx +++ b/src/views/components/MessageMarkdown/Step.tsx @@ -11,19 +11,19 @@ import { keyframes,css } from "@emotion/react"; interface StepProps { language: string; - closed:boolean; children: string; } const Step: React.FC = observer((props) => { const { chat } = useMst(); - const {language,closed,children} = props; + const {language,children} = props; const [opened, { toggle }] = useDisclosure(false); // extract first line with # as button label const lines = children.split('\n'); const title = lines.length>0&&lines[0].indexOf('#')>=0?lines[0].split('#')[1]:''; - + const done = lines[lines.length-1].trim()==='# Done'; + const contents = lines.slice(1,lines.length-1); const spin = keyframes` 0% { transform: rotate(0deg); } @@ -85,7 +85,7 @@ const Step: React.FC = observer((props) => { > : } From cb2ea1deb67ea2909de46b54c2e4be310226a524 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 06/25] Add step component for tutorial content - Split markdown content by ```step blocks - Pass step content to Step component - Step component handles collapsing and highlighting - Support Step and step case insensitive - Extract first line starting with # as step title - Use last line with # Done to show step completed --- package-lock.json | 452 ++++++++++++++++-- package.json | 3 +- src/views/components/MessageMarkdown/Step.tsx | 6 +- .../components/MessageMarkdown/index.tsx | 41 +- 4 files changed, 451 insertions(+), 51 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0fe996..d08db91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,8 @@ "rehype-raw": "^6.1.1", "shell-escape": "^0.2.0", "string-argv": "^0.3.2", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", "uuid": "^9.0.0", "yaml": "^2.3.2" }, @@ -6158,6 +6160,18 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/diff": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", @@ -7545,6 +7559,45 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-raw/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-parse5": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", @@ -11443,6 +11496,17 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/react-markdown/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/react-markdown/node_modules/mdast-util-definitions": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", @@ -11600,6 +11664,24 @@ "inline-style-parser": "0.1.1" } }, + "node_modules/react-markdown/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/react-markdown/node_modules/unist-util-generated": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", @@ -11609,6 +11691,45 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/react-markdown/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/react-markdown/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/react-markdown/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/react-remove-scroll": { "version": "2.5.6", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.6.tgz", @@ -11867,6 +11988,35 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-raw/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rehype-raw/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -13105,23 +13255,28 @@ } }, "node_modules/unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.3.tgz", + "integrity": "sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==", "dependencies": { - "@types/unist": "^2.0.0", + "@types/unist": "^3.0.0", "bail": "^2.0.0", + "devlop": "^1.0.0", "extend": "^3.0.0", - "is-buffer": "^2.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", - "vfile": "^5.0.0" + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, + "node_modules/unified/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, "node_modules/unified/node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", @@ -13133,18 +13288,62 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "node_modules/unified/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", "dependencies": { - "@types/unist": "^2.0.0" + "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, + "node_modules/unified/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, "node_modules/unist-util-position": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", @@ -13170,13 +13369,13 @@ } }, "node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", @@ -13184,18 +13383,28 @@ } }, "node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-visit-parents/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "node_modules/unist-util-visit/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -18634,6 +18843,14 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, + "devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "requires": { + "dequal": "^2.0.0" + } + }, "diff": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", @@ -19667,6 +19884,35 @@ "vfile": "^5.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + } + }, + "unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + } } }, "hast-util-to-parse5": { @@ -22505,6 +22751,11 @@ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==" }, + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + }, "mdast-util-definitions": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", @@ -22620,10 +22871,51 @@ "inline-style-parser": "0.1.1" } }, + "unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + }, "unist-util-generated": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==" + }, + "unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "requires": { + "@types/unist": "^2.0.0" + } + }, + "unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + } + }, + "unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } } } }, @@ -22819,6 +23111,27 @@ "@types/hast": "^2.0.0", "hast-util-raw": "^7.2.0", "unified": "^10.0.0" + }, + "dependencies": { + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + }, + "unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "requires": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + } + } } }, "relateurl": { @@ -23730,32 +24043,71 @@ "dev": true }, "unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.3.tgz", + "integrity": "sha512-jlCV402P+YDcFcB2VcN/n8JasOddqIiaxv118wNBoZXEhOn+lYG7BR4Bfg2BwxvlK58dwbuH2w7GX2esAjL6Mg==", "requires": { - "@types/unist": "^2.0.0", + "@types/unist": "^3.0.0", "bail": "^2.0.0", + "devlop": "^1.0.0", "extend": "^3.0.0", - "is-buffer": "^2.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", - "vfile": "^5.0.0" + "vfile": "^6.0.0" }, "dependencies": { + "@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, "is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + }, + "unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "requires": { + "@types/unist": "^3.0.0" + } + }, + "vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + } + }, + "vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + } } } }, "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "requires": { - "@types/unist": "^2.0.0" + "@types/unist": "^3.0.0" + }, + "dependencies": { + "@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + } } }, "unist-util-position": { @@ -23775,22 +24127,36 @@ } }, "unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "dependencies": { + "@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + } } }, "unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "dependencies": { + "@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + } } }, "unpipe": { diff --git a/package.json b/package.json index 3be8810..42ec88b 100644 --- a/package.json +++ b/package.json @@ -412,7 +412,6 @@ "order": 7, "markdownDescription": "Specify the default llm model for DevChat. [Price of each model](https://devchat.ai/pricing)" }, - "DevChat.OpenAI.stream": { "type": "boolean", "default": true, @@ -807,6 +806,8 @@ "rehype-raw": "^6.1.1", "shell-escape": "^0.2.0", "string-argv": "^0.3.2", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", "uuid": "^9.0.0", "yaml": "^2.3.2" } diff --git a/src/views/components/MessageMarkdown/Step.tsx b/src/views/components/MessageMarkdown/Step.tsx index 905757f..fb3b730 100644 --- a/src/views/components/MessageMarkdown/Step.tsx +++ b/src/views/components/MessageMarkdown/Step.tsx @@ -12,17 +12,17 @@ import { keyframes,css } from "@emotion/react"; interface StepProps { language: string; children: string; + done:boolean; } -const Step: React.FC = observer((props) => { +const Step = observer((props:StepProps) => { const { chat } = useMst(); - const {language,children} = props; + const {language,children,done} = props; const [opened, { toggle }] = useDisclosure(false); // extract first line with # as button label const lines = children.split('\n'); const title = lines.length>0&&lines[0].indexOf('#')>=0?lines[0].split('#')[1]:''; - const done = lines[lines.length-1].trim()==='# Done'; const contents = lines.slice(1,lines.length-1); const spin = keyframes` diff --git a/src/views/components/MessageMarkdown/index.tsx b/src/views/components/MessageMarkdown/index.tsx index 411c62d..3809d75 100644 --- a/src/views/components/MessageMarkdown/index.tsx +++ b/src/views/components/MessageMarkdown/index.tsx @@ -1,5 +1,5 @@ import { Button, Anchor, Stack, Group, Box } from "@mantine/core"; -import React from "react"; +import React, { useEffect, useState } from "react"; import ReactMarkdown from "react-markdown"; import rehypeRaw from "rehype-raw"; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; @@ -11,15 +11,36 @@ import { observer } from "mobx-react-lite"; import { useMst } from "@/views/stores/RootStore"; import { Message } from "@/views/stores/ChatStore"; import messageUtil from '@/util/MessageUtil'; +import {visit} from 'unist-util-visit'; interface MessageMarkdownProps extends React.ComponentProps { children: string, className: string } +type Step = { + index: number, + content: string; + endsWithTripleBacktick: boolean; +}; + const MessageMarkdown = observer((props: MessageMarkdownProps) => { const { children } = props; const { chat } = useMst(); + const [steps, setSteps] = useState([]); + let index = 0; + + useEffect(() => { + const analyzedSteps = children.split(/```step/i).slice(1).map((step,index) => { + const pices = step.split("```"); + return { + index:index, + content:pices[0], + endsWithTripleBacktick: pices.length>1 + }; + }); + setSteps(analyzedSteps); + }, [children]); const handleExplain = (value: string | undefined) => { console.log(value); @@ -119,9 +140,20 @@ Generate a professionally written and formatted release note in markdown with th return (tree) =>{ + visit(tree, function (node) { + if (node.type === 'code' && (node.lang ==='step' || node.lang ==='Step')) { + node.data = { + hProperties:{ + index:index++ + } + }; + } + }); + }]} rehypePlugins={[rehypeRaw]} components={{ - code({ node, inline, className, children, ...props }) { + code({ node, inline, className, children, index=-1, ...props }) { const match = /language-(\w+)/.exec(className || ''); const value = String(children).replace(/\n$/, ''); @@ -135,8 +167,9 @@ Generate a professionally written and formatted release note in markdown with th wrapLongLines = true; } - if (lanugage === 'step') { - return {value}; + if (lanugage === 'step' || lanugage === 'Step') { + const stepInfo = index>=0?steps[index]:{endsWithTripleBacktick:false}; + return {value}; } return !inline && lanugage ? ( From 0886826da7cac036df81f51bfac0cd8938752195 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 07/25] call smartqa --- package.json | 3 + src/contributes/commands.ts | 67 +----------- src/handler/sendMessage.ts | 34 +++--- src/util/uiUtil.ts | 5 + src/util/uiUtil_vscode.ts | 5 + tools/askcode_index_query.py | 207 +++-------------------------------- 6 files changed, 43 insertions(+), 278 deletions(-) diff --git a/package.json b/package.json index 42ec88b..d874a97 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,9 @@ "engines": { "vscode": "^1.75.0" }, + "extensionDependencies": [ + "merico.lang-bridge-vsc" + ], "repository": { "type": "git", "url": "https://github.com/devchat-ai/devchat-vscode.git" diff --git a/src/contributes/commands.ts b/src/contributes/commands.ts index 89510ec..75cffb8 100644 --- a/src/contributes/commands.ts +++ b/src/contributes/commands.ts @@ -284,9 +284,6 @@ export function registerAskCodeIndexStartCommand(context: vscode.ExtensionContex if (!pythonVirtualEnv) { progressBar.update("Installing devchat-ask. See OUTPUT for progress...", 0); await installAskCode(supportedFileTypes, progressBar, indexCode); - } else { - progressBar.update("Index source files. See OUTPUT for progress...", 0); - await indexCode(pythonVirtualEnv, supportedFileTypes, progressBar); } updateIndexingStatus("stopped"); @@ -310,7 +307,7 @@ async function installAskCode(supportedFileTypes, progressBar: any, callback: Fu return; } - UiUtilWrapper.updateConfiguration("DevChat", "PythonVirtualEnv", pythonEnvPath.trim()); + await UiUtilWrapper.updateConfiguration("DevChat", "PythonVirtualEnv", pythonEnvPath.trim()); logger.channel()?.info(`Installation finished.`); // Execute the callback function after the installation is finished @@ -318,68 +315,6 @@ async function installAskCode(supportedFileTypes, progressBar: any, callback: Fu } async function indexCode(pythonVirtualEnv, supportedFileTypes, progressBar: any) { - let envs = {}; - - const llmModelData = await ApiKeyManager.llmModel(); - if (!llmModelData) { - logger.channel()?.error('No valid llm model is selected!'); - logger.channel()?.show(); - - progressBar.endWithError("No valid llm model is selected!"); - return; - } - - let openaiApiKey = llmModelData.api_key; - if (!openaiApiKey) { - logger.channel()?.error('The OpenAI key is invalid!'); - logger.channel()?.show(); - - progressBar.endWithError("The OpenAI key is invalid!"); - return; - } - envs['OPENAI_API_KEY'] = openaiApiKey; - - const openAiApiBase = llmModelData.api_base; - if (openAiApiBase) { - envs['OPENAI_API_BASE'] = openAiApiBase; - } - - const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); - - const command = pythonVirtualEnv.trim(); - const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_index_query.py", "index", ".", supportedFileTypes]; - const options = { env: envs, cwd: workspaceDir }; - - indexProcess = new CommandRun(); - const result = await indexProcess.spawnAsync(command, args, options, (data) => { - if (data.includes('Skip file:')) { - return; - } - logger.channel()?.info(`${data}`); - }, (data) => { - if (data.includes('Skip file:')) { - return; - } - logger.channel()?.info(`${data}`); - }, undefined, undefined); - - if (result.exitCode !== 0) { - if (result.exitCode === null) { - logger.channel()?.info(`Indexing stopped!`); - progressBar.endWithError(`Indexing stopped!`); - } else { - logger.channel()?.error(`Indexing failed: ${result.stderr}`); - logger.channel()?.show(); - progressBar.endWithError(`Indexing failed: ${result.stderr}`); - } - - return; - } - - updateLastModifyTime(); - logger.channel()?.info(`index finished.`); - - progressBar.update("Indexing finished."); progressBar.end(); } diff --git a/src/handler/sendMessage.ts b/src/handler/sendMessage.ts index 4cd1ad8..4dfce09 100644 --- a/src/handler/sendMessage.ts +++ b/src/handler/sendMessage.ts @@ -38,6 +38,8 @@ export async function askCode(message: any, panel: vscode.WebviewPanel|vscode.We _lastMessage = [message]; _lastMessage[0]['askCode'] = true; + const port = await UiUtilWrapper.getLSPBrigePort(); + let pythonVirtualEnv: string|undefined = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv'); if (!pythonVirtualEnv) { try { @@ -80,34 +82,24 @@ export async function askCode(message: any, panel: vscode.WebviewPanel|vscode.We const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); try { - // create temp directory and file - const tempDir = await createTempSubdirectory('devchat/context'); - const tempFile = path.join(tempDir, "doc_context.txt"); - - // If tempFile already exists, delete it - if (fs.existsSync(tempFile)) { - fs.unlinkSync(tempFile); - } - + let outputResult = ""; const commandRun = new CommandRun(); const command = pythonVirtualEnv.trim(); - const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_index_query.py", "query", message.text, tempFile]; + const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_index_query.py", "query", message.text, `${port}`]; const result = await commandRun.spawnAsync(command, args, { env: envs, cwd: workspaceDir }, (data) => { - logger.channel()?.info(data); + outputResult += data; + MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: outputResult, hash:"", user:"", isError: false }); + logger.channel()?.info(data); }, (data) => { logger.channel()?.error(data); }, undefined, undefined); - // Check if tempFile has been written to - if (!fs.existsSync(tempFile) || fs.readFileSync(tempFile, 'utf8') === '') { - logger.channel()?.error(`Did not get relevant context from AskCode.`); - logger.channel()?.show(); - MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: "Did not get relevant context from AskCode.", hash: "", user: "", date: 0, isError: true }); - return; - } - - // Send message - await sendMessage({command: "sendMessage", contextInfo: [{file: tempFile, context: ""}], text: message.text, parent_hash: message.hash}, panel); + if (result.exitCode === 0) { + MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: result.stdout, hash:"", user:"", isError: false }); + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout, hash:"", user:"", date:0, isError: false }); + } else { + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout + result.stderr, hash: "", user: "", date: 0, isError: true }); + } } catch (error) { if (error instanceof Error) { logger.channel()?.error(`error: ${error.message}`); diff --git a/src/util/uiUtil.ts b/src/util/uiUtil.ts index 7bfa125..a083373 100644 --- a/src/util/uiUtil.ts +++ b/src/util/uiUtil.ts @@ -17,6 +17,7 @@ export interface UiUtil { // current selected text selectText(): string | undefined; showErrorMessage(message: string): void; + getLSPBrigePort(): Promise; } @@ -72,5 +73,9 @@ export class UiUtilWrapper { public static showErrorMessage(message: string): void { this._uiUtil?.showErrorMessage(message); } + + public static async getLSPBrigePort(): Promise { + return await this._uiUtil?.getLSPBrigePort(); + } } diff --git a/src/util/uiUtil_vscode.ts b/src/util/uiUtil_vscode.ts index 6d34b09..68ed0d2 100644 --- a/src/util/uiUtil_vscode.ts +++ b/src/util/uiUtil_vscode.ts @@ -122,4 +122,9 @@ export class UiUtilVscode implements UiUtil { public showErrorMessage(message: string): void { vscode.window.showErrorMessage(message); } + + public async getLSPBrigePort(): Promise { + const port = await vscode.commands.executeCommand('LangBrige.getAddress') as number | undefined;; + return port; + } } diff --git a/tools/askcode_index_query.py b/tools/askcode_index_query.py index 8a07f35..2d098c6 100644 --- a/tools/askcode_index_query.py +++ b/tools/askcode_index_query.py @@ -1,210 +1,35 @@ import os -import re import sys -import json -import tempfile -import uuid +from chat.ask_codebase.chains.smart_qa import SmartQA -from chat.ask_codebase.store.qdrant import QdrantWrapper as Q, get_client -from chat.ask_codebase.indexing.embedding import EmbeddingWrapper as E - -from langchain.embeddings import HuggingFaceEmbeddings -from chat.ask_codebase.indexing.loader.file import ( - FileLoader, - FileSource, - gen_local_reference_maker, -) -from chat.util.misc import is_source_code -from chat.ask_codebase.chains.simple_qa import SimpleQA -from chat.ask_codebase.chains.stuff_dc_qa import StuffDocumentCodeQa - - -def get_app_data_dir(app_name): - home = os.path.expanduser("~") - if os.name == "nt": # For Windows - appPath = os.path.join(home, "AppData", "Roaming", app_name) - else: # For Unix and Linux - appPath = os.path.join(home, ".local", "share", app_name) +def query(question, lsp_brige_port): + root_path = os.getcwd() - if not os.path.exists(appPath): - os.makedirs(appPath) - return appPath + # Create an instance of SmartQA + smart_qa = SmartQA(root_path) -supportedFileTypes = [] + # Use SmartQA to get the answer + answer = smart_qa.run(question=question, verbose=True, bridge_url=f'http://localhost:{lsp_brige_port}') -STORAGE_FILE = os.path.join(get_app_data_dir("devchat"), "qdrant_storage2") -SOURCE_NAME = "" - -# 为已经分析的文件记录最后修改时间 -g_file_last_modified_saved = {} - - - -def load_file_last_modified(filePath: str): - # filePath表示存储了文件最后修改时间的文件名,内容实用JSON存储 - # 如果文件不存在,表示尚未进行分析,结束函数执行 - if not os.path.exists(filePath): - return {} - - # 如果文件存在,读取文件内容,解析文件中记录的每一个文件的最后修改时间 - with open(filePath, 'r', encoding="utf-8") as f: - fileLastModified = json.load(f) - - return fileLastModified - - -def save_file_last_modified(filePath: str, fileLastModified: dict): - # filePath表示存储了文件最后修改时间的文件名,内容实用JSON存储 - with open(filePath, 'w+', encoding="utf-8") as f: - json.dump(fileLastModified, f) - - return fileLastModified - -def is_source_code_new(filePath: str): - # 使用正则表达式来判断一个文件是否是源码文件 - for pattern in supportedFileTypes: - if re.match(pattern.strip(), filePath): - return True - return False - -def is_file_modified(filePath: str) -> bool: - if not is_source_code_new(filePath): - return False - - # 获取当前路径 - currentPath = os.getcwd() - # 将filePath转换为相对路径 - relativePath = os.path.relpath(filePath, currentPath) - - # 检查文件路径中是否包含'.xxx'形式的目录 - for part in relativePath.split(os.sep): - if part.startswith('.') or part in ["node_modules", "__pycache__"]: - return False - - # 获取文件上次分析时记录的最后修改时间 - fileLastModified = g_file_last_modified_saved.get(relativePath, 0) - # 获取文件当前的最后修改时间 - fileCurrentModified = os.path.getmtime(filePath) - - # 如果最后修改时间不同,那么更新记录的最后修改时间,并返回True - if fileLastModified != fileCurrentModified: - g_file_last_modified_saved[relativePath] = fileCurrentModified - return True - return False - - -def index(repo_path: str): - try: - client = get_client(STORAGE_FILE) - source = FileSource( - path=repo_path, - rel_root=repo_path, - ref_maker=gen_local_reference_maker(repo_path), - file_filter=is_file_modified, - ) - loader = FileLoader(sources=[source]) - documents = loader.load() - - e = E(embedding=HuggingFaceEmbeddings()) - data = e.embed(documents) - q = Q.create( - source_name=SOURCE_NAME, - embedding_cls=HuggingFaceEmbeddings, - client=client, - ) - - q.insert(data) - except Exception as e: - print(e) - sys.exit(1) - - -import json - -def query(question: str, doc_context: str): - try: - client = get_client(mode=STORAGE_FILE) - q = Q.reuse( - source_name=SOURCE_NAME, - embedding_cls=HuggingFaceEmbeddings, - client=client, - ) - - chain = StuffDocumentCodeQa(q) - - ans, docs = chain.run(question) - - print(f"\n# Question: \n{question}") - print(f"\n# Answer: \n{ans}") - print(f"\n# Relevant Documents: \n") - doc_dict = {"path": "AskCode Context","content": json.dumps([{"filepath": d.metadata.get('filepath'), "content": d.page_content} for d in docs])} - with open(doc_context, 'w') as f: - json.dump(doc_dict, f) - for d in docs: - print(f"- filepath: {d.metadata.get('filepath')}") - print(f" location: {d.metadata.get('reference')}\n") - - print(f"Save doc context to {doc_context}") - except Exception as e: - print(e) - sys.exit(1) + # Print the answer + print(answer[0]) def main(): try: - global supportedFileTypes - - if len(sys.argv) < 2: - print("Usage: python index_and_query.py [command] [args]") - print("Available commands: index, query") + if len(sys.argv) < 4: + print("Usage: python index_and_query.py query [question] [port]") sys.exit(1) - command = sys.argv[1] - - if command == "index": - if len(sys.argv) < 4: - print("Usage: python index_and_query.py index [repo_path] [supportedFileTypes]") - sys.exit(1) - - repo_path = sys.argv[2] - # 获取supportedFileTypes的值 - supportedFileTypes = sys.argv[3].split(',') - index(repo_path) - - elif command == "query": - if len(sys.argv) < 4: - print("Usage: python index_and_query.py query [question] [doc_context]") - sys.exit(1) - - question = sys.argv[2] - doc_context = sys.argv[3] - query(question, doc_context) - - else: - print("Invalid command. Available commands: index, query") - sys.exit(1) + question = sys.argv[2] + port = sys.argv[3] + query(question, port) + sys.exit(0) except Exception as e: print(e) sys.exit(1) if __name__ == "__main__": - try: - currentPath = os.getcwd() - g_file_last_modified_saved = load_file_last_modified('./.chat/.index_modified.json') - if os.path.exists(".chat/askcode.json"): - with open(".chat/askcode.json", "r") as f: - askcode_data = json.load(f) - SOURCE_NAME = askcode_data.get("SOURCE_NAME", str(uuid.uuid4())) - else: - SOURCE_NAME = str(uuid.uuid4()) - currentPath = os.getcwd() - with open(".chat/askcode.json", "w+") as f: - json.dump({"SOURCE_NAME": SOURCE_NAME}, f) - main() - save_file_last_modified('./.chat/.index_modified.json', g_file_last_modified_saved) - sys.exit(0) - except Exception as e: - print(e) - sys.exit(1) \ No newline at end of file + main() \ No newline at end of file From 822ea8f18a7a3dd964d69d9d829a0c717dafac1f Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 08/25] support stop while ask-code --- src/handler/sendMessage.ts | 151 +++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 64 deletions(-) diff --git a/src/handler/sendMessage.ts b/src/handler/sendMessage.ts index 4dfce09..df616b8 100644 --- a/src/handler/sendMessage.ts +++ b/src/handler/sendMessage.ts @@ -15,6 +15,9 @@ import { CommandRun, createTempSubdirectory } from '../util/commonUtil'; const exec = promisify(execCb); +let askcode_stop = true; +let askcode_runner : CommandRun | null = null; + let _lastMessage: any = undefined; export function createTempFile(content: string): string { @@ -35,80 +38,91 @@ export function deleteTempFiles(fileName: string): void { regInMessage({command: 'askCode', text: '', parent_hash: undefined}); regOutMessage({ command: 'receiveMessage', text: 'xxxx', hash: 'xxx', user: 'xxx', date: 'xxx'}); export async function askCode(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise { - _lastMessage = [message]; - _lastMessage[0]['askCode'] = true; + try { + askcode_stop = false; + askcode_runner = null; - const port = await UiUtilWrapper.getLSPBrigePort(); + _lastMessage = [message]; + _lastMessage[0]['askCode'] = true; - let pythonVirtualEnv: string|undefined = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv'); - if (!pythonVirtualEnv) { - try { - await vscode.commands.executeCommand('DevChat.AskCodeIndexStart'); - } catch (error) { - logger.channel()?.error(`Failed to execute command ${message.content[0]}: ${error}`); + const port = await UiUtilWrapper.getLSPBrigePort(); + + let pythonVirtualEnv: string|undefined = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv'); + if (!pythonVirtualEnv) { + try { + await vscode.commands.executeCommand('DevChat.AskCodeIndexStart'); + } catch (error) { + logger.channel()?.error(`Failed to execute command ${message.content[0]}: ${error}`); + logger.channel()?.show(); + return; + } + + pythonVirtualEnv = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv'); + if (!pythonVirtualEnv) { + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: "Index code fail.", hash: "", user: "", date: 0, isError: true }); + return ; + } + } + + let envs = {}; + + const llmModelData = await ApiKeyManager.llmModel(); + if (!llmModelData) { + logger.channel()?.error('No valid llm model is selected!'); logger.channel()?.show(); return; } - pythonVirtualEnv = vscode.workspace.getConfiguration('DevChat').get('PythonVirtualEnv'); - if (!pythonVirtualEnv) { - MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: "Index code fail.", hash: "", user: "", date: 0, isError: true }); - return ; + let openaiApiKey = llmModelData.api_key; + if (!openaiApiKey) { + logger.channel()?.error('The OpenAI key is invalid!'); + logger.channel()?.show(); + return; } - } + envs['OPENAI_API_KEY'] = openaiApiKey; - let envs = {}; + const openAiApiBase = llmModelData.api_base; + if (openAiApiBase) { + envs['OPENAI_API_BASE'] = openAiApiBase; + } - const llmModelData = await ApiKeyManager.llmModel(); - if (!llmModelData) { - logger.channel()?.error('No valid llm model is selected!'); - logger.channel()?.show(); - return; + const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); + if (askcode_stop) { + return; + } + + try { + let outputResult = ""; + askcode_runner = new CommandRun(); + const command = pythonVirtualEnv.trim(); + const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_index_query.py", "query", message.text, `${port}`]; + const result = await askcode_runner.spawnAsync(command, args, { env: envs, cwd: workspaceDir }, (data) => { + outputResult += data; + MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: outputResult, hash:"", user:"", isError: false }); + logger.channel()?.info(data); + }, (data) => { + logger.channel()?.error(data); + }, undefined, undefined); + + if (result.exitCode === 0) { + MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: result.stdout, hash:"", user:"", isError: false }); + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout, hash:"", user:"", date:0, isError: false }); + } else { + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout + result.stderr, hash: "", user: "", date: 0, isError: true }); + } + } catch (error) { + if (error instanceof Error) { + logger.channel()?.error(`error: ${error.message}`); + } else { + logger.channel()?.error(`An unknown error occurred: ${error}`); + } + logger.channel()?.show(); + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: "Did not get relevant context from AskCode.", hash: "", user: "", date: 0, isError: true }); + } + } finally { + askcode_stop = true; + askcode_runner = null; } - - let openaiApiKey = llmModelData.api_key; - if (!openaiApiKey) { - logger.channel()?.error('The OpenAI key is invalid!'); - logger.channel()?.show(); - return; - } - envs['OPENAI_API_KEY'] = openaiApiKey; - - const openAiApiBase = llmModelData.api_base; - if (openAiApiBase) { - envs['OPENAI_API_BASE'] = openAiApiBase; - } - - const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); - - try { - let outputResult = ""; - const commandRun = new CommandRun(); - const command = pythonVirtualEnv.trim(); - const args = [UiUtilWrapper.extensionPath() + "/tools/askcode_index_query.py", "query", message.text, `${port}`]; - const result = await commandRun.spawnAsync(command, args, { env: envs, cwd: workspaceDir }, (data) => { - outputResult += data; - MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: outputResult, hash:"", user:"", isError: false }); - logger.channel()?.info(data); - }, (data) => { - logger.channel()?.error(data); - }, undefined, undefined); - - if (result.exitCode === 0) { - MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: result.stdout, hash:"", user:"", isError: false }); - MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout, hash:"", user:"", date:0, isError: false }); - } else { - MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout + result.stderr, hash: "", user: "", date: 0, isError: true }); - } - } catch (error) { - if (error instanceof Error) { - logger.channel()?.error(`error: ${error.message}`); - } else { - logger.channel()?.error(`An unknown error occurred: ${error}`); - } - logger.channel()?.show(); - MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: "Did not get relevant context from AskCode.", hash: "", user: "", date: 0, isError: true }); - } } @@ -191,6 +205,15 @@ export async function regeneration(message: any, panel: vscode.WebviewPanel|vsco regInMessage({command: 'stopDevChat'}); export async function stopDevChat(message: any, panel: vscode.WebviewPanel|vscode.WebviewView): Promise { stopDevChatBase(message); + + if (askcode_stop === false) { + askcode_stop = true; + if (askcode_runner) { + askcode_runner.stop(); + askcode_runner = null; + } + await vscode.commands.executeCommand('DevChat.AskCodeIndexStop'); + } } regInMessage({command: 'deleteChatMessage', hash: 'xxx'}); From 962f8ca161254e0c1b7b8e88ab9a5f3188fda5a4 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 09/25] Refactor query function in askcode_index_query.py - Updated the query function in askcode_index_query.py to include additional parameters for controlling the DFS algorithm. - Changed the verbose parameter to False in the call to smart_qa.run() to reduce console output. --- tools/askcode_index_query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/askcode_index_query.py b/tools/askcode_index_query.py index 2d098c6..1d413c9 100644 --- a/tools/askcode_index_query.py +++ b/tools/askcode_index_query.py @@ -10,7 +10,7 @@ def query(question, lsp_brige_port): smart_qa = SmartQA(root_path) # Use SmartQA to get the answer - answer = smart_qa.run(question=question, verbose=True, bridge_url=f'http://localhost:{lsp_brige_port}') + answer = smart_qa.run(question=question, verbose=False, dfs_depth=3, dfs_max_visit=10, bridge_url=f'http://localhost:{lsp_brige_port}' ) # Print the answer print(answer[0]) From b214ddfc7141716e9245154312b4fc22fa115b90 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 10/25] Refactor Step component in MessageMarkdown - Removed unnecessary empty fragment tags (<>) surrounding the Accordion component. - Updated the return statement to directly return the Accordion component. - Removed unnecessary closing tag () at the end of the return statement. - Removed unused imports. --- src/views/components/MessageMarkdown/Step.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/views/components/MessageMarkdown/Step.tsx b/src/views/components/MessageMarkdown/Step.tsx index fb3b730..69a285e 100644 --- a/src/views/components/MessageMarkdown/Step.tsx +++ b/src/views/components/MessageMarkdown/Step.tsx @@ -30,8 +30,7 @@ const Step = observer((props:StepProps) => { 100% { transform: rotate(360deg); } `; - return <> - {lines.length > 1 && { - } - ; + ; }); export default Step; \ No newline at end of file From 46e3e1edfc02fa58ebb06def664a7f852ec5f080 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 11/25] Add mdast-related dependencies and update code to use mdast - Update package.json to include mdast dependencies - Import necessary functions and types from mdast-util - Update logic to use mdast functions and types - Update rendering logic to work with new mdast structure --- package-lock.json | 1138 +++++++++++++++++ package.json | 7 +- src/views/components/CurrentMessage/index.tsx | 24 +- 3 files changed, 1157 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index d08db91..ba62493 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,9 @@ "axios": "^1.3.6", "dotenv": "^16.0.3", "js-yaml": "^4.1.0", + "mdast": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", "mobx": "^6.10.0", "mobx-react": "^9.0.0", "mobx-state-tree": "^5.1.8", @@ -9330,6 +9333,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -9454,6 +9466,327 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/mdast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast/-/mdast-3.0.0.tgz", + "integrity": "sha512-xySmf8g4fPKMeC07jXGz971EkLbWAJ83s4US2Tj9lEdnZ142UP5grN73H1Xd3HzrdbU5o9GYYP/y8F9ZSwLE9g==", + "deprecated": "`mdast` was renamed to `remark`" + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.0.tgz", + "integrity": "sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-from-markdown/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", + "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing/node_modules/@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "node_modules/mdast-util-to-markdown/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.0.tgz", + "integrity": "sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-to-markdown/node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string/node_modules/@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -9510,6 +9843,40 @@ "node": ">= 0.6" } }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, "node_modules/micromark-core-commonmark": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz", @@ -9898,6 +10265,372 @@ } ] }, + "node_modules/micromark/node_modules/micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.0.tgz", + "integrity": "sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-subtokenize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", + "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -21213,6 +21946,11 @@ "is-unicode-supported": "^0.1.0" } }, + "longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -21315,6 +22053,204 @@ } } }, + "mdast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast/-/mdast-3.0.0.tgz", + "integrity": "sha512-xySmf8g4fPKMeC07jXGz971EkLbWAJ83s4US2Tj9lEdnZ142UP5grN73H1Xd3HzrdbU5o9GYYP/y8F9ZSwLE9g==" + }, + "mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "requires": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "dependencies": { + "@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "requires": { + "@types/unist": "*" + } + }, + "@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.0.tgz", + "integrity": "sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + }, + "micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==" + }, + "unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "requires": { + "@types/unist": "^3.0.0" + } + } + } + }, + "mdast-util-phrasing": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", + "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", + "requires": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "dependencies": { + "@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "requires": { + "@types/unist": "*" + } + } + } + }, + "mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "requires": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "dependencies": { + "@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "requires": { + "@types/unist": "*" + } + }, + "@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.0.tgz", + "integrity": "sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + }, + "micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==" + } + } + }, + "mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "requires": { + "@types/mdast": "^4.0.0" + }, + "dependencies": { + "@types/mdast": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.1.tgz", + "integrity": "sha512-IlKct1rUTJ1T81d8OHzyop15kGv9A/ff7Gz7IJgrk6jDb4Udw77pCJ+vq8oxZf4Ghpm+616+i1s/LNg/Vh7d+g==", + "requires": { + "@types/unist": "*" + } + } + } + }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -21359,6 +22295,208 @@ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true }, + "micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "requires": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "dependencies": { + "micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "requires": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "requires": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "requires": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "requires": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", + "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "requires": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "requires": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.0.tgz", + "integrity": "sha512-pIgcsGxpHEtTG/rPJRz/HOLSqp5VTuIIjXlPI+6JSDlK2oljApusG6KzpS8AF0ENUMCHlC/IBb5B9xdFiVlm5Q==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==" + }, + "micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==" + }, + "micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "requires": { + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "requires": { + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "requires": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "micromark-util-subtokenize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", + "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "requires": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==" + }, + "micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==" + } + } + }, "micromark-core-commonmark": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz", diff --git a/package.json b/package.json index d874a97..dabc34f 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,8 @@ "vscode": "^1.75.0" }, "extensionDependencies": [ - "merico.lang-bridge-vsc" - ], + "merico.lang-bridge-vsc" + ], "repository": { "type": "git", "url": "https://github.com/devchat-ai/devchat-vscode.git" @@ -796,6 +796,9 @@ "axios": "^1.3.6", "dotenv": "^16.0.3", "js-yaml": "^4.1.0", + "mdast": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", "mobx": "^6.10.0", "mobx-react": "^9.0.0", "mobx-state-tree": "^5.1.8", diff --git a/src/views/components/CurrentMessage/index.tsx b/src/views/components/CurrentMessage/index.tsx index fbe0991..db72bca 100644 --- a/src/views/components/CurrentMessage/index.tsx +++ b/src/views/components/CurrentMessage/index.tsx @@ -1,12 +1,14 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { keyframes } from "@emotion/react"; import { Box, Container, Text } from "@mantine/core"; import MessageBody from "@/views/components/MessageBody"; import { observer } from "mobx-react-lite"; import { useMst } from "@/views/stores/RootStore"; import { Message } from "@/views/stores/ChatStore"; - +import {fromMarkdown} from 'mdast-util-from-markdown'; +import {toMarkdown} from 'mdast-util-to-markdown'; +import {Root} from 'mdast'; const MessageBlink = observer(() => { const { chat } = useMst(); @@ -49,13 +51,12 @@ const CurrentMessage = observer((props: any) => { const { width } = props; const { chat } = useMst(); const { messages, currentMessage, generating, responsed, hasDone } = chat; - // split blocks - const messageBlocks = getBlocks(currentMessage); - const lastMessageBlocks = getBlocks(messages[messages.length - 1]?.message); - const fixedCount = lastMessageBlocks.length; - const receivedCount = messageBlocks.length; - const renderBlocks = messageBlocks.splice(-1); + const messageBlocks = fromMarkdown(currentMessage); + const lastMessageBlocks = fromMarkdown(messages[messages.length - 1]?.message); + const fixedCount = lastMessageBlocks.children.length; + const receivedCount = messageBlocks.children.length; + const renderBlocks = messageBlocks.children.splice(-1); useEffect(() => { if (generating) { @@ -67,7 +68,10 @@ const CurrentMessage = observer((props: any) => { useEffect(() => { if (generating && (receivedCount - fixedCount >= 1 || !responsed)) { - chat.updateLastMessage(currentMessage); + chat.updateLastMessage(toMarkdown({ + type: 'root', + children: messageBlocks.children + })); } }, [currentMessage, responsed, generating]); @@ -86,7 +90,7 @@ const CurrentMessage = observer((props: any) => { whiteSpace: 'break-spaces' }, }}> - + 0?toMarkdown(renderBlocks[0]):''} messageType="bot" /> : <>; From d5093825385ca92a65a3ca9b47850566b2d7db49 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 12/25] Refactor MessageMarkdown, MessageBody, CurrentMessage, and MessageList components MessageMarkdown: - Removed unused imports. - Modified useEffect() to analyze steps using mdast-util-from-markdown instead of splitting children directly. - Modified code component to set the 'index' property based on the order of 'code' nodes in the tree. MessageBody: - Removed the messageText prop and replaced it with children prop to allow more flexibility in passing content. - Updated the usage of MessageMarkdown to pass the temp prop as needed. CurrentMessage: - Removed unused import for 'mdast'. - Modified marginTop value to always be '1em' instead of conditionally set based on chat.responsed. MessageList: - Updated the usage of MessageBody to pass the messageText as children prop. MessageMarkdown: - Updated the code component to determine the 'done' prop based on the index and the presence of 'code' nodes. Note: The changes in the components involve refactoring and improving the code structure and functionality. --- src/views/components/CurrentMessage/index.tsx | 10 ++++-- src/views/components/MessageBody/index.tsx | 13 +++++--- src/views/components/MessageList/index.tsx | 4 ++- .../components/MessageMarkdown/index.tsx | 31 +++++++------------ 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/views/components/CurrentMessage/index.tsx b/src/views/components/CurrentMessage/index.tsx index db72bca..b4c942c 100644 --- a/src/views/components/CurrentMessage/index.tsx +++ b/src/views/components/CurrentMessage/index.tsx @@ -8,7 +8,6 @@ import { useMst } from "@/views/stores/RootStore"; import { Message } from "@/views/stores/ChatStore"; import {fromMarkdown} from 'mdast-util-from-markdown'; import {toMarkdown} from 'mdast-util-to-markdown'; -import {Root} from 'mdast'; const MessageBlink = observer(() => { const { chat } = useMst(); @@ -20,7 +19,7 @@ const MessageBlink = observer(() => { return |; @@ -84,13 +83,18 @@ const CurrentMessage = observer((props: any) => { return generating ? - 0?toMarkdown(renderBlocks[0]):''} messageType="bot" /> + + {renderBlocks.length>0?toMarkdown(renderBlocks[0]):''} + : <>; diff --git a/src/views/components/MessageBody/index.tsx b/src/views/components/MessageBody/index.tsx index 6be4b12..3d35533 100644 --- a/src/views/components/MessageBody/index.tsx +++ b/src/views/components/MessageBody/index.tsx @@ -5,8 +5,9 @@ import MessageMarkdown from "@/views/components/MessageMarkdown"; import { useMst } from "@/views/stores/RootStore"; interface IProps { - messageText: string, - messageType: string + messageType: string, + children: string, + temp?: boolean } @@ -17,14 +18,16 @@ const useStyles = createStyles((theme, options:any) => ({ })); const MessageBody = observer((props: IProps) => { - const { messageText, messageType } = props; + const { children, messageType, temp=false } = props; const { chat } = useMst(); const {classes} = useStyles({ chatPanelWidth:chat.chatPanelWidth }); return ( messageType === 'bot' - ? {messageText} + ? + {children} + : { wordBreak: 'break-word', }, }}> -
{messageText}
+
{children}
); }); diff --git a/src/views/components/MessageList/index.tsx b/src/views/components/MessageList/index.tsx index a26b90e..35a9bd7 100644 --- a/src/views/components/MessageList/index.tsx +++ b/src/views/components/MessageList/index.tsx @@ -41,7 +41,9 @@ const MessageList = observer((props: any) => { }, }}> - + + {messageText} + {index !== chat.messages.length - 1 && } ; diff --git a/src/views/components/MessageMarkdown/index.tsx b/src/views/components/MessageMarkdown/index.tsx index 3809d75..80ec8bf 100644 --- a/src/views/components/MessageMarkdown/index.tsx +++ b/src/views/components/MessageMarkdown/index.tsx @@ -11,11 +11,13 @@ import { observer } from "mobx-react-lite"; import { useMst } from "@/views/stores/RootStore"; import { Message } from "@/views/stores/ChatStore"; import messageUtil from '@/util/MessageUtil'; +import {fromMarkdown} from 'mdast-util-from-markdown'; import {visit} from 'unist-util-visit'; interface MessageMarkdownProps extends React.ComponentProps { children: string, - className: string + className: string, + temp?: boolean } type Step = { @@ -25,22 +27,13 @@ type Step = { }; const MessageMarkdown = observer((props: MessageMarkdownProps) => { - const { children } = props; + const { children,temp=false } = props; const { chat } = useMst(); const [steps, setSteps] = useState([]); - let index = 0; - - useEffect(() => { - const analyzedSteps = children.split(/```step/i).slice(1).map((step,index) => { - const pices = step.split("```"); - return { - index:index, - content:pices[0], - endsWithTripleBacktick: pices.length>1 - }; - }); - setSteps(analyzedSteps); - }, [children]); + const tree = fromMarkdown(children); + const codes = tree.children.filter(node => node.type === 'code'); + const lastNode = tree.children[tree.children.length-1]; + let index = 1; const handleExplain = (value: string | undefined) => { console.log(value); @@ -145,7 +138,7 @@ Generate a professionally written and formatted release note in markdown with th if (node.type === 'code' && (node.lang ==='step' || node.lang ==='Step')) { node.data = { hProperties:{ - index:index++ + index: index++ } }; } @@ -153,7 +146,7 @@ Generate a professionally written and formatted release note in markdown with th }]} rehypePlugins={[rehypeRaw]} components={{ - code({ node, inline, className, children, index=-1, ...props }) { + code({ node, inline, className, children, index, ...props }) { const match = /language-(\w+)/.exec(className || ''); const value = String(children).replace(/\n$/, ''); @@ -168,8 +161,8 @@ Generate a professionally written and formatted release note in markdown with th } if (lanugage === 'step' || lanugage === 'Step') { - const stepInfo = index>=0?steps[index]:{endsWithTripleBacktick:false}; - return {value}; + let done = Number(index) < codes.length? true : lastNode.type !== 'code'; + return {value}; } return !inline && lanugage ? ( From 230f7cc872e697e3bf56d15b7cb19bb9ebc71cb4 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 13/25] Add confirm property to Message model and devchatAsk method - Add a `confirm` property to the `Message` model in the `ChatStore.ts` file. - Add a `devchatAsk` method to create a user message followed by a bot message with the `confirm` property set to `true`. --- src/views/components/MessageList/index.tsx | 45 +++++++++++++++++++++- src/views/stores/ChatStore.ts | 16 ++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/views/components/MessageList/index.tsx b/src/views/components/MessageList/index.tsx index 35a9bd7..f1009fc 100644 --- a/src/views/components/MessageList/index.tsx +++ b/src/views/components/MessageList/index.tsx @@ -1,5 +1,5 @@ -import { Stack, Container, Divider, Box } from "@mantine/core"; +import { Stack, Container, Divider, Box, Group,Text, Button, createStyles } from "@mantine/core"; import React, { useEffect } from "react"; import MessageBody from "@/views/components/MessageBody"; import MessageAvatar from "@/views/components/MessageAvatar"; @@ -8,14 +8,42 @@ import { useMst } from "@/views/stores/RootStore"; import { Message } from "@/views/stores/ChatStore"; import MessageContext from "@/views/components/MessageContext"; import CurrentMessage from "@/views/components/CurrentMessage"; +import { Card } from '@mantine/core'; +import { IconInfoSquareRounded } from "@tabler/icons-react"; +const useStyles = createStyles((theme) => ({ + card:{ + backgroundColor: 'var(--vscode-menu-background)', + fontFamily: 'var(--vscode-editor-font-familyy)', + fontSize: 'var(--vscode-editor-font-size)', + color: 'var(--vscode-menu-foreground)', + borderColor: 'var(--vscode-menu-border)', + }, + cardDescription:{ + marginTop: 10, + marginBottom: 10, + }, + button:{ + backgroundColor:"#ED6A45", + color:"#fff", + "&:hover":{ + backgroundColor:"#ED6A45", + opacity: 0.8, + }, + "&:focus":{ + backgroundColor:"#ED6A45", + opacity: 0.8, + } + } + })); const MessageList = observer((props: any) => { const { chat } = useMst(); + const {classes} = useStyles(); return ( {chat.messages.map((item, index: number) => { - const { message: messageText, type: messageType, hash: messageHash, contexts } = item; + const { message: messageText, type: messageType, hash: messageHash, contexts, confirm } = item; // setMessage(messageText); return { whiteSpace: 'break-spaces' }, }}> + { messageType === 'bot' && + + + + Additional Cost Required + + + Will you pay approximately $1.2 - $ 2.2 for this task? + + + + + } {messageText} diff --git a/src/views/stores/ChatStore.ts b/src/views/stores/ChatStore.ts index a4f9f18..5ff1f75 100644 --- a/src/views/stores/ChatStore.ts +++ b/src/views/stores/ChatStore.ts @@ -61,6 +61,7 @@ export const Message = types.model({ type: types.enumeration(['user', 'bot', 'system']), message: types.string, contexts: types.maybe(types.array(ChatContext)), + confirm: types.maybe(types.boolean) }); export const ChatStore = types.model('Chat', { @@ -113,8 +114,23 @@ You can configure DevChat from [Settings](#settings).`; })); }; + const devchatAsk = (userMessage) => { + self.messages.push( + Message.create({ + type: 'user', + message: userMessage + })); + self.messages.push( + Message.create({ + type: 'bot', + message: '', + confirm: true + })); + }; + return { helpMessage, + devchatAsk, updateChatPanelWidth: (width: number) => { self.chatPanelWidth = width; }, From 7c8da398aeacf977cbb5b74b2e6aff5453f1f65b Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 14/25] Refactor message generation and handling in CurrentMessage and InputMessage components - Remove the useEffect hook in CurrentMessage that creates a bot message when `generating` is true. This logic is now handled elsewhere. - Update the onSubmit handler in InputMessage to distinguish between different types of user input and call the appropriate methods in the ChatStore. - Add the `startGenerating`, `commonMessage`, `goScrollBottom`, `sendLastUserMessage`, `cancelDevchatAsk` methods to the ChatStore to handle message generation and display. - Extract the `contextInfo` function to convert chat contexts to the required format for sending to the extension. --- src/views/components/CurrentMessage/index.tsx | 8 -- src/views/components/InputMessage/index.tsx | 28 ++-- src/views/stores/ChatStore.ts | 123 +++++++++++++----- 3 files changed, 97 insertions(+), 62 deletions(-) diff --git a/src/views/components/CurrentMessage/index.tsx b/src/views/components/CurrentMessage/index.tsx index b4c942c..3727846 100644 --- a/src/views/components/CurrentMessage/index.tsx +++ b/src/views/components/CurrentMessage/index.tsx @@ -57,14 +57,6 @@ const CurrentMessage = observer((props: any) => { const receivedCount = messageBlocks.children.length; const renderBlocks = messageBlocks.children.splice(-1); - useEffect(() => { - if (generating) { - // new a bot message - const messageItem = Message.create({ type: 'bot', message: currentMessage }); - chat.newMessage(messageItem); - } - }, [generating]); - useEffect(() => { if (generating && (receivedCount - fixedCount >= 1 || !responsed)) { chat.updateLastMessage(toMarkdown({ diff --git a/src/views/components/InputMessage/index.tsx b/src/views/components/InputMessage/index.tsx index 25aa409..7b54a06 100644 --- a/src/views/components/InputMessage/index.tsx +++ b/src/views/components/InputMessage/index.tsx @@ -60,27 +60,19 @@ const InputMessage = observer((props: any) => { if (inputValue) { if (inputValue.trim() === '/help') { chat.helpMessage(); - input.setValue(''); - event.preventDefault(); - } else{ + } else { const text = inputValue; - // Add the user's message to the chat UI const chatContexts = contexts ? [...contexts].map((item) => ({ ...item })) : undefined; - const newMessage = Message.create({ - type: 'user', - message: inputValue, - contexts: chatContexts - }); - chat.newMessage(newMessage); - // start generating - chat.startGenerating(text, chatContexts); - // Clear the input field - input.setValue(''); - input.clearContexts(); - setTimeout(() => { - chat.goScrollBottom(); - }, 1000); + if (inputValue.trim().startsWith('/ask-code')) { + chat.devchatAsk(text, chatContexts); + } else{ + chat.commonMessage(text, chatContexts); + } } + // Clear the input field + input.setValue(''); + input.clearContexts(); + event.preventDefault(); } }; diff --git a/src/views/stores/ChatStore.ts b/src/views/stores/ChatStore.ts index 5ff1f75..67d716d 100644 --- a/src/views/stores/ChatStore.ts +++ b/src/views/stores/ChatStore.ts @@ -83,6 +83,34 @@ export const ChatStore = types.model('Chat', { }) .actions(self => { + const goScrollBottom = () => { + self.scrollBottom++; + }; + + const lastNonEmptyHash = () => { + let lastNonEmptyHash; + for (let i = self.messages.length - 1; i >= 0; i--) { + if (self.messages[i].hash) { + lastNonEmptyHash = self.messages[i].hash; + break; + } + } + return lastNonEmptyHash === 'message' ? null : lastNonEmptyHash; + }; + + // Process and send the message to the extension + const contextInfo = chatContexts => chatContexts.map((item, index: number) => { + const { file, path, content, command } = item; + return { + file, + context: { + path: path, + command: command, + content: content, + } + }; + }); + const helpMessage = (originalMessage = false) => { let helps = ` @@ -112,12 +140,15 @@ You can configure DevChat from [Settings](#settings).`; type: 'bot', message: helps })); + // goto bottom + goScrollBottom(); }; - const devchatAsk = (userMessage) => { + const devchatAsk = (userMessage, chatContexts) => { self.messages.push( Message.create({ type: 'user', + contexts: chatContexts, message: userMessage })); self.messages.push( @@ -126,11 +157,66 @@ You can configure DevChat from [Settings](#settings).`; message: '', confirm: true })); + // goto bottom + goScrollBottom(); }; + const startGenerating = (text: string, chatContexts) => { + self.generating = true; + self.responsed = false; + self.hasDone = false; + self.errorMessage = ''; + self.currentMessage = ''; + messageUtil.sendMessage({ + command: 'sendMessage', + text: text, + contextInfo: contextInfo(chatContexts), + parent_hash: lastNonEmptyHash() + }); + }; + + const sendLastUserMessage = () => { + const lastUserMessage = self.messages[self.messages.length - 2]; + const lastBotMessage = self.messages[self.messages.length - 1]; + if (lastUserMessage && lastUserMessage.type === 'user') { + lastBotMessage.confirm = false; + startGenerating(lastUserMessage.message, lastUserMessage.contexts); + } + }; + + const cancelDevchatAsk = () => { + const lastBotMessage = self.messages[self.messages.length - 1]; + if (lastBotMessage && lastBotMessage.type === 'bot') { + lastBotMessage.confirm = false; + lastBotMessage.message = 'No problem, let me know if you have any other questions or if there\'s anything else I can help you with.'; + } + }; + + const commonMessage = (text: string, chatContexts) => { + self.messages.push({ + type: 'user', + message: text, + contexts: chatContexts + }); + self.messages.push({ + type: 'bot', + message: '' + }); + // start generating + startGenerating(text, chatContexts); + // goto bottom + goScrollBottom(); + }; + + return { helpMessage, devchatAsk, + sendLastUserMessage, + cancelDevchatAsk, + goScrollBottom, + startGenerating, + commonMessage, updateChatPanelWidth: (width: number) => { self.chatPanelWidth = width; }, @@ -140,38 +226,6 @@ You can configure DevChat from [Settings](#settings).`; updateFeatures: (features: any) => { self.features = features; }, - startGenerating: (text: string, chatContexts) => { - self.generating = true; - self.responsed = false; - self.hasDone = false; - self.errorMessage = ''; - self.currentMessage = ''; - let lastNonEmptyHash; - for (let i = self.messages.length - 1; i >= 0; i--) { - if (self.messages[i].hash) { - lastNonEmptyHash = self.messages[i].hash; - break; - } - } - // Process and send the message to the extension - const contextInfo = chatContexts.map((item, index: number) => { - const { file, path, content, command } = item; - return { - file, - context: { - path: path, - command: command, - content: content, - } - }; - }); - messageUtil.sendMessage({ - command: 'sendMessage', - text: text, - contextInfo: contextInfo, - parent_hash: lastNonEmptyHash === 'message' ? null : lastNonEmptyHash - }); - }, startSystemMessage: () => { self.generating = true; self.responsed = false; @@ -245,9 +299,6 @@ You can configure DevChat from [Settings](#settings).`; self.isTop = false; self.isBottom = false; }, - goScrollBottom: () => { - self.scrollBottom++; - }, fetchHistoryMessages: flow(function* (params: { pageIndex: number }) { const { pageIndex, entries } = yield fetchHistoryMessages(params); if (entries.length > 0) { From 386ab58631df45a4714acae7ca82d6c260fae1e6 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 15/25] Update MessageList component - Add conditional rendering for confirm button based on 'confirm' prop value - Update onClick event handlers for 'Yes' and 'No' buttons to call appropriate functions --- src/views/components/MessageList/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/components/MessageList/index.tsx b/src/views/components/MessageList/index.tsx index f1009fc..22286f0 100644 --- a/src/views/components/MessageList/index.tsx +++ b/src/views/components/MessageList/index.tsx @@ -68,7 +68,7 @@ const MessageList = observer((props: any) => { whiteSpace: 'break-spaces' }, }}> - { messageType === 'bot' && + { messageType === 'bot' && confirm && @@ -77,8 +77,8 @@ const MessageList = observer((props: any) => { Will you pay approximately $1.2 - $ 2.2 for this task? - - + + } From 6c07272bf2e2953f85e40bcdfea9223035a13099 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 16/25] Update bot message in ChatStore.ts - Updated the message in the ChatStore.ts file to improve clarity and provide assistance to the user. --- src/views/stores/ChatStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/stores/ChatStore.ts b/src/views/stores/ChatStore.ts index 67d716d..022f8ba 100644 --- a/src/views/stores/ChatStore.ts +++ b/src/views/stores/ChatStore.ts @@ -188,7 +188,7 @@ You can configure DevChat from [Settings](#settings).`; const lastBotMessage = self.messages[self.messages.length - 1]; if (lastBotMessage && lastBotMessage.type === 'bot') { lastBotMessage.confirm = false; - lastBotMessage.message = 'No problem, let me know if you have any other questions or if there\'s anything else I can help you with.'; + lastBotMessage.message = 'You\'ve cancelled the question. Please let me know if you have any other questions or if there\'s anything else I can assist with.'; } }; From 96b811fc3fbc1a3ddd1d5bebfa56cf1f0129f503 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 17/25] Update cost range in MessageList component - Updated the cost range displayed in the MessageList component from approximately $1.2 - $2.2 to approximately $0.1 - $0.5. --- src/views/components/MessageList/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/components/MessageList/index.tsx b/src/views/components/MessageList/index.tsx index 22286f0..2fec144 100644 --- a/src/views/components/MessageList/index.tsx +++ b/src/views/components/MessageList/index.tsx @@ -75,7 +75,7 @@ const MessageList = observer((props: any) => { Additional Cost Required - Will you pay approximately $1.2 - $ 2.2 for this task? + Will you pay approximately $0.1 - $0.5 for this task? From c51c8189d0f0f1510a6fc9f8e4b1bec8ba3bc078 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 18/25] Refactor MessageList component - Updated the styles in the MessageList component including the button font family and font size. - Modified the Card component to always be displayed for 'bot' messages. - Updated the text description of the cost range to approximately $0.1 - $0.5. - Modified the size and color of the buttons for user interaction. --- src/views/components/MessageList/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/views/components/MessageList/index.tsx b/src/views/components/MessageList/index.tsx index 2fec144..1190e96 100644 --- a/src/views/components/MessageList/index.tsx +++ b/src/views/components/MessageList/index.tsx @@ -25,6 +25,8 @@ const useStyles = createStyles((theme) => ({ }, button:{ backgroundColor:"#ED6A45", + fontFamily: 'var(--vscode-editor-font-familyy)', + fontSize: 'var(--vscode-editor-font-size)', color:"#fff", "&:hover":{ backgroundColor:"#ED6A45", @@ -68,7 +70,7 @@ const MessageList = observer((props: any) => { whiteSpace: 'break-spaces' }, }}> - { messageType === 'bot' && confirm && + { messageType === 'bot' && @@ -77,8 +79,8 @@ const MessageList = observer((props: any) => { Will you pay approximately $0.1 - $0.5 for this task? - - + + } From c9f01f7373025033afcf75829c29f5e4d250d51b Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 19/25] Insert ask-code result to devchat --- src/handler/sendMessage.ts | 10 +++++- src/handler/sendMessageBase.ts | 5 +++ src/toolwrapper/devchat.ts | 58 ++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/handler/sendMessage.ts b/src/handler/sendMessage.ts index df616b8..1d4f777 100644 --- a/src/handler/sendMessage.ts +++ b/src/handler/sendMessage.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import { MessageHandler } from './messageHandler'; import { regInMessage, regOutMessage } from '../util/reg_messages'; -import { stopDevChatBase, sendMessageBase, deleteChatMessageBase } from './sendMessageBase'; +import { stopDevChatBase, sendMessageBase, deleteChatMessageBase, insertDevChatLog } from './sendMessageBase'; import { UiUtilWrapper } from '../util/uiUtil'; import * as fs from 'fs'; import * as os from 'os'; @@ -107,6 +107,14 @@ export async function askCode(message: any, panel: vscode.WebviewPanel|vscode.We if (result.exitCode === 0) { MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: result.stdout, hash:"", user:"", isError: false }); MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout, hash:"", user:"", date:0, isError: false }); + + // save askcode result to devchat + const step_index = result.stdout.lastIndexOf("```Step"); + const step_end_index = result.stdout.lastIndexOf("```"); + if (step_index > 0 && step_end_index > 0) { + const result_out = result.stdout.substring(step_end_index+3, result.stdout.length); + await insertDevChatLog(message, "/ask-code " + message.text, result_out) + } } else { MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout + result.stderr, hash: "", user: "", date: 0, isError: true }); } diff --git a/src/handler/sendMessageBase.ts b/src/handler/sendMessageBase.ts index a5a1669..10b732f 100644 --- a/src/handler/sendMessageBase.ts +++ b/src/handler/sendMessageBase.ts @@ -178,6 +178,11 @@ export async function stopDevChatBase(message: any): Promise { devChat.stop(); } +export async function insertDevChatLog(message: any, request: string, response: string): Promise { + logger.channel()?.info(`Inserting devchat log`); + await devChat.logInsert(request, response, message.parent_hash); +} + // delete a chat message // each message is identified by hash export async function deleteChatMessageBase(message:{'hash': string}): Promise { diff --git a/src/toolwrapper/devchat.ts b/src/toolwrapper/devchat.ts index d2196a6..a302577 100644 --- a/src/toolwrapper/devchat.ts +++ b/src/toolwrapper/devchat.ts @@ -301,6 +301,64 @@ class DevChat { } } + async logInsert(request: string, response: string, parent: string | undefined) { + let log_data = { + "model": "gpt-4", + "messages": [ + { + "role": "user", + "content": request + }, + { + "role": "assistant", + "content": response + } + ], + "timestamp": Date.now(), + "request_tokens": 1, + "response_tokens": 1 + }; + if (parent) { + log_data["parent"] = parent; + } + + + const args = ["log", "--insert", JSON.stringify(log_data)]; + const devChat = this.getDevChatPath(); + const workspaceDir = UiUtilWrapper.workspaceFoldersFirstPath(); + const openaiApiKey = process.env.OPENAI_API_KEY; + + logger.channel()?.info(`Running devchat with arguments: ${args.join(" ")}`); + const spawnOptions = { + maxBuffer: 10 * 1024 * 1024, // Set maxBuffer to 10 MB + cwd: workspaceDir, + env: { + ...process.env, + OPENAI_API_KEY: openaiApiKey, + }, + }; + const { exitCode: code, stdout, stderr } = await this.commandRun.spawnAsync(devChat, args, spawnOptions, undefined, undefined, undefined, undefined); + + logger.channel()?.info(`Finish devchat with arguments: ${args.join(" ")}`); + if (stderr) { + logger.channel()?.error(`Error: ${stderr}`); + logger.channel()?.show(); + return false; + } + if (stdout.indexOf('Failed to insert log') >= 0) { + logger.channel()?.error(`Failed to insert log: ${log_data}`); + logger.channel()?.show(); + return false; + } + + if (code !== 0) { + logger.channel()?.error(`Exit code: ${code}`); + logger.channel()?.show(); + return false; + } + return true; + } + async delete(hash: string): Promise { const args = ["log", "--delete", hash]; const devChat = this.getDevChatPath(); From d74757b5449f704e135c51fbf46a20b34db663eb Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 20/25] Refactor MessageList component - Add a condition to render the 'Card' component only when 'confirm' is true. - This change ensures that the 'Card' component is only displayed for bot messages when the 'confirm' prop is true. --- src/views/components/MessageList/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/components/MessageList/index.tsx b/src/views/components/MessageList/index.tsx index 1190e96..925fa9b 100644 --- a/src/views/components/MessageList/index.tsx +++ b/src/views/components/MessageList/index.tsx @@ -70,7 +70,7 @@ const MessageList = observer((props: any) => { whiteSpace: 'break-spaces' }, }}> - { messageType === 'bot' && + { messageType === 'bot' && confirm && From b00da5eec5ada58820eb8422dad2e9a90b481b64 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 21/25] Update commandManager.ts and MessageList/index.tsx - Update the description for the 'ask-code' command in commandManager.ts - Update the text in MessageList/index.tsx to promote the '/ask-code' command and provide additional information about the AI agent and pricing --- src/command/commandManager.ts | 2 +- src/views/components/MessageList/index.tsx | 9 +++++-- .../components/MessageMarkdown/index.tsx | 24 +++---------------- src/views/stores/ChatStore.ts | 2 +- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/command/commandManager.ts b/src/command/commandManager.ts index 8f4271d..ef168c6 100644 --- a/src/command/commandManager.ts +++ b/src/command/commandManager.ts @@ -26,7 +26,7 @@ class CommandManager { CommandManager.instance.registerCommand({ name: 'ask-code', pattern: 'ask-code', - description: 'ask code', + description: 'Ask anything about your codebase and get answers from our AI agent', args: 0, handler: async (commandName: string, userInput: string) => { return ''; diff --git a/src/views/components/MessageList/index.tsx b/src/views/components/MessageList/index.tsx index 925fa9b..d153419 100644 --- a/src/views/components/MessageList/index.tsx +++ b/src/views/components/MessageList/index.tsx @@ -74,10 +74,15 @@ const MessageList = observer((props: any) => { - Additional Cost Required + Explore with /ask-code! - Will you pay approximately $0.1 - $0.5 for this task? + + /ask-code, your AI agent, navigates through your codebase to answer questions using GPT-4, analyzing up to 10 source files for approximately $0.4 USD per question. We're evolving — soon, we'll implement the more affordable LLama2-70b model. +
+
+ Would you like to proceed? +
diff --git a/src/views/components/MessageMarkdown/index.tsx b/src/views/components/MessageMarkdown/index.tsx index 80ec8bf..a7d2329 100644 --- a/src/views/components/MessageMarkdown/index.tsx +++ b/src/views/components/MessageMarkdown/index.tsx @@ -46,27 +46,9 @@ const MessageMarkdown = observer((props: MessageMarkdownProps) => { }), Message.create({ type: 'bot', - message: `***/ask_code*** - -If you would like to ask questions related to your own codebase, you can enable and use the /ask_code feature of DevChat. - -While /ask_code is being enabled, DevChat will need to index your codebase before you can use this feature. Indexing usually takes a while, depending on the size of your codebase, your computing power and the network. Once it’s done, you can ask questions about your codebase by typing the “/ask_code” command, followed by your question. - -Example questions: -(Here we only show example questions from a few popular open-source projects’ codebases.) - -How do I access POST form fields in Express? -How do I pass command line arguments to a Node.js program? -How do I print the value of a tensor object in TensorFlow? -How do I force Kubernetes to re-pull an image in Kubernetes? -How do I set focus on an input field after rendering in React? - -\`Please check DevChat.ask_code settings\` before enabling the feature, because once indexing has been started, changing the settings will not affect the process anymore, unless if you terminate it and re-index. - -To enable, you can enter \`DevChat:Start AskCode Index\` in the Command Palette or click on the button to start indexing now. - - - + message: `***/ask-code*** + +Your AI agent, navigates through your codebase to answer questions using GPT-4, analyzing up to 10 source files for approximately $0.4 USD per question. We're evolving — soon, we'll implement the more affordable LLama2-70b model. ` }), ]); diff --git a/src/views/stores/ChatStore.ts b/src/views/stores/ChatStore.ts index 022f8ba..64d4732 100644 --- a/src/views/stores/ChatStore.ts +++ b/src/views/stores/ChatStore.ts @@ -126,7 +126,7 @@ To get started, here are some of the things that I can do for you: [/release_note: draft a release note based on your latest commits](#release_note) -${self.features['ask-code'] ? '[/ask-code: ask me questions about your codebase](#ask_code)' : ''} +${self.features['ask-code'] ? '[/ask-code: ask anything about your codebase and get answers from our AI agent](#ask_code)' : ''} You can configure DevChat from [Settings](#settings).`; From 3ede604e4eee96b4b58347507afbd096cae4b0d4 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Wed, 11 Oct 2023 23:51:57 +0800 Subject: [PATCH 22/25] update devchat version --- src/contributes/commandsBase.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contributes/commandsBase.ts b/src/contributes/commandsBase.ts index d55a496..21c3013 100644 --- a/src/contributes/commandsBase.ts +++ b/src/contributes/commandsBase.ts @@ -14,7 +14,7 @@ export function checkDevChatDependency(showError: boolean = true): boolean { try { // Check if DevChat is installed - const expectVersion = 'DevChat 0.2.8'; + const expectVersion = 'DevChat 0.2.9'; const devchatVersion = runCommand(`"${devChat}" --version`).toString().trim(); if (devchatVersion < expectVersion) { logger.channel()?.info(`devchat version: ${devchatVersion}, but expect version: ${expectVersion}`); From 9964a1891e184331cd59643fd9496168557ffe62 Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Wed, 11 Oct 2023 23:51:58 +0800 Subject: [PATCH 23/25] fix timestampt while insert log --- src/handler/sendMessage.ts | 22 ++++++++++++++-------- src/handler/sendMessageBase.ts | 8 +++++++- src/toolwrapper/devchat.ts | 2 +- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/handler/sendMessage.ts b/src/handler/sendMessage.ts index 1d4f777..03b0842 100644 --- a/src/handler/sendMessage.ts +++ b/src/handler/sendMessage.ts @@ -105,16 +105,22 @@ export async function askCode(message: any, panel: vscode.WebviewPanel|vscode.We }, undefined, undefined); if (result.exitCode === 0) { - MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: result.stdout, hash:"", user:"", isError: false }); - MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout, hash:"", user:"", date:0, isError: false }); - // save askcode result to devchat - const step_index = result.stdout.lastIndexOf("```Step"); - const step_end_index = result.stdout.lastIndexOf("```"); - if (step_index > 0 && step_end_index > 0) { - const result_out = result.stdout.substring(step_end_index+3, result.stdout.length); - await insertDevChatLog(message, "/ask-code " + message.text, result_out) + const stepIndex = result.stdout.lastIndexOf("```Step"); + const stepEndIndex = result.stdout.lastIndexOf("```"); + let resultOut = result.stdout; + if (stepIndex > 0 && stepEndIndex > 0) { + resultOut = result.stdout.substring(stepEndIndex+3, result.stdout.length); } + let logHash = await insertDevChatLog(message, "/ask-code " + message.text, resultOut); + if (!logHash) { + logHash = ""; + logger.channel()?.error(`Failed to insert devchat log.`); + logger.channel()?.show(); + } + + MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: result.stdout, hash:logHash, user:"", isError: false }); + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout, hash:logHash, user:"", date:0, isError: false }); } else { MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout + result.stderr, hash: "", user: "", date: 0, isError: true }); } diff --git a/src/handler/sendMessageBase.ts b/src/handler/sendMessageBase.ts index 10b732f..472c427 100644 --- a/src/handler/sendMessageBase.ts +++ b/src/handler/sendMessageBase.ts @@ -178,9 +178,15 @@ export async function stopDevChatBase(message: any): Promise { devChat.stop(); } -export async function insertDevChatLog(message: any, request: string, response: string): Promise { +export async function insertDevChatLog(message: any, request: string, response: string): Promise { logger.channel()?.info(`Inserting devchat log`); await devChat.logInsert(request, response, message.parent_hash); + const logs = await devChat.log({"maxCount": 1}); + if (logs && logs.length > 0) { + return logs[0]['hash']; + } else { + return undefined; + } } // delete a chat message diff --git a/src/toolwrapper/devchat.ts b/src/toolwrapper/devchat.ts index a302577..fb1bad7 100644 --- a/src/toolwrapper/devchat.ts +++ b/src/toolwrapper/devchat.ts @@ -314,7 +314,7 @@ class DevChat { "content": response } ], - "timestamp": Date.now(), + "timestamp": Math.floor(Date.now()/1000), "request_tokens": 1, "response_tokens": 1 }; From ce25ef98a941e8a5cd103294662e4d6fe1de49ef Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Wed, 11 Oct 2023 23:51:58 +0800 Subject: [PATCH 24/25] update topic after ask-code response --- src/handler/sendMessage.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/handler/sendMessage.ts b/src/handler/sendMessage.ts index 03b0842..24b151a 100644 --- a/src/handler/sendMessage.ts +++ b/src/handler/sendMessage.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import { MessageHandler } from './messageHandler'; import { regInMessage, regOutMessage } from '../util/reg_messages'; -import { stopDevChatBase, sendMessageBase, deleteChatMessageBase, insertDevChatLog } from './sendMessageBase'; +import { stopDevChatBase, sendMessageBase, deleteChatMessageBase, insertDevChatLog, handleTopic } from './sendMessageBase'; import { UiUtilWrapper } from '../util/uiUtil'; import * as fs from 'fs'; import * as os from 'os'; @@ -121,8 +121,15 @@ export async function askCode(message: any, panel: vscode.WebviewPanel|vscode.We MessageHandler.sendMessage(panel, { command: 'receiveMessagePartial', text: result.stdout, hash:logHash, user:"", isError: false }); MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout, hash:logHash, user:"", date:0, isError: false }); + + const dateStr = Math.floor(Date.now()/1000).toString(); + await handleTopic( + message.parent_hash, + {"text": "/ask-code " + message.text}, + { response: result.stdout, "prompt-hash": logHash, user: "", "date": dateStr, finish_reason: "", isError: false }); } else { - MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stdout + result.stderr, hash: "", user: "", date: 0, isError: true }); + logger.channel()?.info(`${result.stdout}`); + MessageHandler.sendMessage(panel, { command: 'receiveMessage', text: result.stderr, hash: "", user: "", date: 0, isError: true }); } } catch (error) { if (error instanceof Error) { From b0dcd1b32ab497ce3df3f039c8b0a5c88bf681ff Mon Sep 17 00:00:00 2001 From: "bobo.yang" Date: Thu, 12 Oct 2023 00:13:17 +0800 Subject: [PATCH 25/25] add pre-release flag --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0a4c6b0..7ea44aa 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,7 +25,7 @@ jobs: sed -i "s/\"version\": \".*\",/\"version\": \"${CIRCLE_TAG:1}\",/" package.json - run: name: "Publish to Marketplace" - command: npx vsce publish -p $VSCE_TOKEN --allow-star-activation + command: npx vsce publish -p $VSCE_TOKEN --allow-star-activation --pre-release workflows: version: 2 build-and-publish: