summaryrefslogtreecommitdiff
path: root/extension/react-app
diff options
context:
space:
mode:
Diffstat (limited to 'extension/react-app')
-rw-r--r--extension/react-app/index.html2
-rw-r--r--extension/react-app/package-lock.json1473
-rw-r--r--extension/react-app/package.json2
-rw-r--r--extension/react-app/public/vite.svg1
-rw-r--r--extension/react-app/src/App.tsx19
-rw-r--r--extension/react-app/src/TestPage.tsx33
-rw-r--r--extension/react-app/src/assets/Hubot-Sans.woff2bin165932 -> 0 bytes
-rw-r--r--extension/react-app/src/assets/Mona-Sans.woff2bin133748 -> 0 bytes
-rw-r--r--extension/react-app/src/assets/react.svg1
-rw-r--r--extension/react-app/src/components/CodeMultiselect.tsx276
-rw-r--r--extension/react-app/src/components/ComboBox.tsx135
-rw-r--r--extension/react-app/src/components/InputAndButton.tsx10
-rw-r--r--extension/react-app/src/components/LoadingCover.tsx50
-rw-r--r--extension/react-app/src/components/Onboarding.tsx136
-rw-r--r--extension/react-app/src/components/PillButton.tsx170
-rw-r--r--extension/react-app/src/components/StepContainer.tsx116
-rw-r--r--extension/react-app/src/components/TextDialog.tsx21
-rw-r--r--extension/react-app/src/components/index.ts23
-rw-r--r--extension/react-app/src/highlight/dark.min.css53
-rw-r--r--extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts35
-rw-r--r--extension/react-app/src/hooks/ContinueGUIClientProtocol.ts93
-rw-r--r--extension/react-app/src/hooks/messenger.ts10
-rw-r--r--extension/react-app/src/hooks/useContinueGUIProtocol.ts91
-rw-r--r--extension/react-app/src/hooks/useWebsocket.ts2
-rw-r--r--extension/react-app/src/index.css4
-rw-r--r--extension/react-app/src/pages/gui.tsx (renamed from extension/react-app/src/tabs/gui.tsx)49
-rw-r--r--extension/react-app/src/tabs/additionalContext.tsx18
-rw-r--r--extension/react-app/src/tabs/chat/MessageDiv.tsx75
-rw-r--r--extension/react-app/src/tabs/chat/index.tsx267
-rw-r--r--extension/react-app/src/tabs/main.tsx189
-rw-r--r--extension/react-app/src/tabs/welcome.tsx22
-rw-r--r--extension/react-app/src/util/api.ts43
-rw-r--r--extension/react-app/src/util/editCache.ts89
-rw-r--r--extension/react-app/src/util/index.ts62
34 files changed, 2059 insertions, 1511 deletions
diff --git a/extension/react-app/index.html b/extension/react-app/index.html
index e0d1c840..043c307e 100644
--- a/extension/react-app/index.html
+++ b/extension/react-app/index.html
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+ <link rel="icon" type="image/svg+xml" href="/play_button.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
diff --git a/extension/react-app/package-lock.json b/extension/react-app/package-lock.json
index 7316581d..13e02e86 100644
--- a/extension/react-app/package-lock.json
+++ b/extension/react-app/package-lock.json
@@ -11,12 +11,12 @@
"@styled-icons/heroicons-outline": "^10.47.0",
"@styled-icons/heroicons-solid": "^10.47.0",
"@types/vscode-webview": "^1.57.1",
+ "@uiw/react-markdown-preview": "^4.1.13",
"downshift": "^7.6.0",
"posthog-js": "^1.58.0",
"prismjs": "^1.29.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-markdown": "^8.0.5",
"react-redux": "^8.0.5",
"react-switch": "^7.0.0",
"react-syntax-highlighter": "^15.5.0",
@@ -963,6 +963,16 @@
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
},
+ "node_modules/@types/parse5": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz",
+ "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g=="
+ },
+ "node_modules/@types/prismjs": {
+ "version": "1.26.0",
+ "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.0.tgz",
+ "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ=="
+ },
"node_modules/@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
@@ -1027,6 +1037,34 @@
"resolved": "https://registry.npmjs.org/@types/vscode-webview/-/vscode-webview-1.57.1.tgz",
"integrity": "sha512-ghW5SfuDmsGDS2A4xkvGsLwDRNc3Vj5rS6rPOyPm/IryZuf3wceZKxgYaUoW+k9f0f/CB7y2c1rRsdOWZWn0PQ=="
},
+ "node_modules/@uiw/copy-to-clipboard": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/@uiw/copy-to-clipboard/-/copy-to-clipboard-1.0.15.tgz",
+ "integrity": "sha512-1bbGZ3T+SGmA07BoVPK4UCUDcowDN/moctviJGQexfOc9qL8TMLDQPr7mTPvDKhgJkgnlKkAQNFU8PiarIi9sQ=="
+ },
+ "node_modules/@uiw/react-markdown-preview": {
+ "version": "4.1.13",
+ "resolved": "https://registry.npmjs.org/@uiw/react-markdown-preview/-/react-markdown-preview-4.1.13.tgz",
+ "integrity": "sha512-fmIGvBpK6HJyDFf7EokjZSIS0713Bq5KwhOsZ8IkbCMYDcDThFlmMkTTqyzGjL3phrkP9ED5O63WSILzefqe6A==",
+ "dependencies": {
+ "@babel/runtime": "^7.17.2",
+ "@uiw/copy-to-clipboard": "~1.0.12",
+ "react-markdown": "~8.0.0",
+ "rehype-attr": "~2.1.0",
+ "rehype-autolink-headings": "~6.1.1",
+ "rehype-ignore": "^1.0.1",
+ "rehype-prism-plus": "~1.5.0",
+ "rehype-raw": "^6.1.1",
+ "rehype-rewrite": "~3.0.6",
+ "rehype-slug": "~5.1.0",
+ "remark-gfm": "~3.0.1",
+ "unist-util-visit": "^4.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
"node_modules/@vitejs/plugin-react-swc": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.2.0.tgz",
@@ -1163,6 +1201,15 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/bcp-47-match": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz",
+ "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -1172,6 +1219,11 @@
"node": ">=8"
}
},
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
+ },
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
@@ -1245,6 +1297,15 @@
}
]
},
+ "node_modules/ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -1370,6 +1431,11 @@
"node": ">=4"
}
},
+ "node_modules/css-selector-parser": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz",
+ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g=="
+ },
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
@@ -1473,6 +1539,18 @@
"node": ">=0.3.1"
}
},
+ "node_modules/direction": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz",
+ "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==",
+ "bin": {
+ "direction": "cli.js"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
@@ -1684,6 +1762,11 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
+ "node_modules/github-slugger": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
+ "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -1729,6 +1812,86 @@
"node": ">=4"
}
},
+ "node_modules/hast-util-from-parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz",
+ "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "@types/unist": "^2.0.0",
+ "hastscript": "^7.0.0",
+ "property-information": "^6.0.0",
+ "vfile": "^5.0.0",
+ "vfile-location": "^4.0.0",
+ "web-namespaces": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-from-parse5/node_modules/hast-util-parse-selector": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
+ "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==",
+ "dependencies": {
+ "@types/hast": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-from-parse5/node_modules/hastscript": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz",
+ "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-parse-selector": "^3.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-has-property": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz",
+ "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-heading-rank": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-2.1.1.tgz",
+ "integrity": "sha512-iAuRp+ESgJoRFJbSyaqsfvJDY6zzmFoEnL1gtz1+U8gKtGGj1p0CVlysuUAUjq95qlZESHINLThwJzNGmgGZxA==",
+ "dependencies": {
+ "@types/hast": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-is-element": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz",
+ "integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "@types/unist": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-parse-selector": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
@@ -1738,6 +1901,83 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/hast-util-raw": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz",
+ "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "@types/parse5": "^6.0.0",
+ "hast-util-from-parse5": "^7.0.0",
+ "hast-util-to-parse5": "^7.0.0",
+ "html-void-elements": "^2.0.0",
+ "parse5": "^6.0.0",
+ "unist-util-position": "^4.0.0",
+ "unist-util-visit": "^4.0.0",
+ "vfile": "^5.0.0",
+ "web-namespaces": "^2.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-select": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-5.0.5.tgz",
+ "integrity": "sha512-QQhWMhgTFRhCaQdgTKzZ5g31GLQ9qRb1hZtDPMqQaOhpLBziWcshUS0uCR5IJ0U1jrK/mxg35fmcq+Dp/Cy2Aw==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "@types/unist": "^2.0.0",
+ "bcp-47-match": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "css-selector-parser": "^1.0.0",
+ "direction": "^2.0.0",
+ "hast-util-has-property": "^2.0.0",
+ "hast-util-to-string": "^2.0.0",
+ "hast-util-whitespace": "^2.0.0",
+ "not": "^0.1.0",
+ "nth-check": "^2.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "unist-util-visit": "^4.0.0",
+ "zwitch": "^2.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",
+ "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "web-namespaces": "^2.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-to-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz",
+ "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==",
+ "dependencies": {
+ "@types/hast": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-whitespace": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz",
@@ -1814,6 +2054,15 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/html-void-elements": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz",
+ "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/inline-style-parser": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
@@ -1995,6 +2244,15 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "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",
@@ -2019,6 +2277,15 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/markdown-table": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
+ "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/mdast-util-definitions": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz",
@@ -2033,6 +2300,32 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdast-util-find-and-replace": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz",
+ "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "escape-string-regexp": "^5.0.0",
+ "unist-util-is": "^5.0.0",
+ "unist-util-visit-parents": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/mdast-util-from-markdown": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.0.tgz",
@@ -2056,6 +2349,107 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdast-util-gfm": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz",
+ "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==",
+ "dependencies": {
+ "mdast-util-from-markdown": "^1.0.0",
+ "mdast-util-gfm-autolink-literal": "^1.0.0",
+ "mdast-util-gfm-footnote": "^1.0.0",
+ "mdast-util-gfm-strikethrough": "^1.0.0",
+ "mdast-util-gfm-table": "^1.0.0",
+ "mdast-util-gfm-task-list-item": "^1.0.0",
+ "mdast-util-to-markdown": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-autolink-literal": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz",
+ "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "ccount": "^2.0.0",
+ "mdast-util-find-and-replace": "^2.0.0",
+ "micromark-util-character": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-footnote": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz",
+ "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-markdown": "^1.3.0",
+ "micromark-util-normalize-identifier": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-strikethrough": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz",
+ "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-markdown": "^1.3.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-table": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz",
+ "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "markdown-table": "^3.0.0",
+ "mdast-util-from-markdown": "^1.0.0",
+ "mdast-util-to-markdown": "^1.3.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-task-list-item": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz",
+ "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-markdown": "^1.3.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-phrasing": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz",
+ "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "unist-util-is": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/mdast-util-to-hast": {
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz",
@@ -2075,6 +2469,25 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/mdast-util-to-markdown": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz",
+ "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "@types/unist": "^2.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-phrasing": "^3.0.0",
+ "mdast-util-to-string": "^3.0.0",
+ "micromark-util-decode-string": "^1.0.0",
+ "unist-util-visit": "^4.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/mdast-util-to-string": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.1.tgz",
@@ -2163,6 +2576,120 @@
"uvu": "^0.5.0"
}
},
+ "node_modules/micromark-extension-gfm": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz",
+ "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==",
+ "dependencies": {
+ "micromark-extension-gfm-autolink-literal": "^1.0.0",
+ "micromark-extension-gfm-footnote": "^1.0.0",
+ "micromark-extension-gfm-strikethrough": "^1.0.0",
+ "micromark-extension-gfm-table": "^1.0.0",
+ "micromark-extension-gfm-tagfilter": "^1.0.0",
+ "micromark-extension-gfm-task-list-item": "^1.0.0",
+ "micromark-util-combine-extensions": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-autolink-literal": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz",
+ "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==",
+ "dependencies": {
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-sanitize-uri": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-footnote": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz",
+ "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==",
+ "dependencies": {
+ "micromark-core-commonmark": "^1.0.0",
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-normalize-identifier": "^1.0.0",
+ "micromark-util-sanitize-uri": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-strikethrough": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz",
+ "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==",
+ "dependencies": {
+ "micromark-util-chunked": "^1.0.0",
+ "micromark-util-classify-character": "^1.0.0",
+ "micromark-util-resolve-all": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-table": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz",
+ "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==",
+ "dependencies": {
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-tagfilter": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz",
+ "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==",
+ "dependencies": {
+ "micromark-util-types": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-task-list-item": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz",
+ "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==",
+ "dependencies": {
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/micromark-factory-destination": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz",
@@ -2589,6 +3116,22 @@
"node": ">=0.10.0"
}
},
+ "node_modules/not": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz",
+ "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA=="
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -2632,6 +3175,16 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/parse-numeric-range": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz",
+ "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ=="
+ },
+ "node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
+ },
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -3047,6 +3600,257 @@
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
+ "node_modules/rehype-attr": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/rehype-attr/-/rehype-attr-2.1.4.tgz",
+ "integrity": "sha512-iAeaL5JyF4XxkcvWzpi/0SAF7iV7qOTaHS56tJuEsXziQc3+PEmMn65kV8OFgbO9mRVY7J1fRC/aLvot1PsNkg==",
+ "dependencies": {
+ "unified": "~10.1.1",
+ "unist-util-visit": "~4.1.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/rehype-autolink-headings": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-6.1.1.tgz",
+ "integrity": "sha512-NMYzZIsHM3sA14nC5rAFuUPIOfg+DFmf9EY1YMhaNlB7+3kK/ZlE6kqPfuxr1tsJ1XWkTrMtMoyHosU70d35mA==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "extend": "^3.0.0",
+ "hast-util-has-property": "^2.0.0",
+ "hast-util-heading-rank": "^2.0.0",
+ "hast-util-is-element": "^2.0.0",
+ "unified": "^10.0.0",
+ "unist-util-visit": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-ignore": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/rehype-ignore/-/rehype-ignore-1.0.5.tgz",
+ "integrity": "sha512-JQXS5eDwXaYKwB8JEYFJJA/YvGi0sSNUOYuiURMtuPTg8tuWHFB91JMYLbImH1FyvyGQM4fIBqNMAPB50WR2Bw==",
+ "dependencies": {
+ "hast-util-select": "^5.0.5",
+ "unified": "^10.1.2",
+ "unist-util-visit": "^4.1.2"
+ },
+ "engines": {
+ "node": "^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/rehype-parse": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.4.tgz",
+ "integrity": "sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "hast-util-from-parse5": "^7.0.0",
+ "parse5": "^6.0.0",
+ "unified": "^10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-prism-plus": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/rehype-prism-plus/-/rehype-prism-plus-1.5.1.tgz",
+ "integrity": "sha512-mowYefSfrIkMMxkb0fwuEXlvc5nA9b1vQ6mzujM81Qx28RI0mo7jCHsBZ2tJ4eIJKXdFn+EdPkZZBGB10K02vg==",
+ "dependencies": {
+ "hast-util-to-string": "^2.0.0",
+ "parse-numeric-range": "^1.3.0",
+ "refractor": "^4.7.0",
+ "rehype-parse": "^8.0.2",
+ "unist-util-filter": "^4.0.0",
+ "unist-util-visit": "^4.0.0"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/hast-util-parse-selector": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
+ "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==",
+ "dependencies": {
+ "@types/hast": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/hastscript": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz",
+ "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-parse-selector": "^3.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/parse-entities": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz",
+ "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-prism-plus/node_modules/refractor": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-4.8.1.tgz",
+ "integrity": "sha512-/fk5sI0iTgFYlmVGYVew90AoYnNMP6pooClx/XKqyeeCQXrL0Kvgn8V0VEht5ccdljbzzF1i3Q213gcntkRExg==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "@types/prismjs": "^1.0.0",
+ "hastscript": "^7.0.0",
+ "parse-entities": "^4.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/rehype-raw": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz",
+ "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "hast-util-raw": "^7.2.0",
+ "unified": "^10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/rehype-rewrite": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/rehype-rewrite/-/rehype-rewrite-3.0.6.tgz",
+ "integrity": "sha512-REDTNCvsKcAazy8IQWzKp66AhSUDSOIKssSCqNqCcT9sN7JCwAAm3mWGTUdUzq80ABuy8d0D6RBwbnewu1aY1g==",
+ "dependencies": {
+ "hast-util-select": "~5.0.1",
+ "unified": "~10.1.1",
+ "unist-util-visit": "~4.1.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/rehype-slug": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-5.1.0.tgz",
+ "integrity": "sha512-Gf91dJoXneiorNEnn+Phx97CO7oRMrpi+6r155tTxzGuLtm+QrI4cTwCa9e1rtePdL4i9tSO58PeSS6HWfgsiw==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "github-slugger": "^2.0.0",
+ "hast-util-has-property": "^2.0.0",
+ "hast-util-heading-rank": "^2.0.0",
+ "hast-util-to-string": "^2.0.0",
+ "unified": "^10.0.0",
+ "unist-util-visit": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-gfm": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz",
+ "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==",
+ "dependencies": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-gfm": "^2.0.0",
+ "micromark-extension-gfm": "^2.0.0",
+ "unified": "^10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/remark-parse": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz",
@@ -3365,6 +4169,16 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/unist-util-filter": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-filter/-/unist-util-filter-4.0.1.tgz",
+ "integrity": "sha512-RynicUM/vbOSTSiUK+BnaK9XMfmQUh6gyi7L6taNgc7FIf84GukXVV3ucGzEN/PhUUkdP5hb1MmXc+3cvPUm5Q==",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^5.0.0",
+ "unist-util-visit-parents": "^5.0.0"
+ }
+ },
"node_modules/unist-util-generated": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz",
@@ -3517,6 +4331,19 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/vfile-location": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz",
+ "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "vfile": "^5.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/vfile-message": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz",
@@ -3587,6 +4414,15 @@
"fs-extra": "^10.0.0"
}
},
+ "node_modules/web-namespaces": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
+ "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -3603,6 +4439,15 @@
"engines": {
"node": ">= 6"
}
+ },
+ "node_modules/zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
}
},
"dependencies": {
@@ -4143,6 +4988,16 @@
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
},
+ "@types/parse5": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz",
+ "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g=="
+ },
+ "@types/prismjs": {
+ "version": "1.26.0",
+ "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.0.tgz",
+ "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ=="
+ },
"@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
@@ -4207,6 +5062,30 @@
"resolved": "https://registry.npmjs.org/@types/vscode-webview/-/vscode-webview-1.57.1.tgz",
"integrity": "sha512-ghW5SfuDmsGDS2A4xkvGsLwDRNc3Vj5rS6rPOyPm/IryZuf3wceZKxgYaUoW+k9f0f/CB7y2c1rRsdOWZWn0PQ=="
},
+ "@uiw/copy-to-clipboard": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/@uiw/copy-to-clipboard/-/copy-to-clipboard-1.0.15.tgz",
+ "integrity": "sha512-1bbGZ3T+SGmA07BoVPK4UCUDcowDN/moctviJGQexfOc9qL8TMLDQPr7mTPvDKhgJkgnlKkAQNFU8PiarIi9sQ=="
+ },
+ "@uiw/react-markdown-preview": {
+ "version": "4.1.13",
+ "resolved": "https://registry.npmjs.org/@uiw/react-markdown-preview/-/react-markdown-preview-4.1.13.tgz",
+ "integrity": "sha512-fmIGvBpK6HJyDFf7EokjZSIS0713Bq5KwhOsZ8IkbCMYDcDThFlmMkTTqyzGjL3phrkP9ED5O63WSILzefqe6A==",
+ "requires": {
+ "@babel/runtime": "^7.17.2",
+ "@uiw/copy-to-clipboard": "~1.0.12",
+ "react-markdown": "~8.0.0",
+ "rehype-attr": "~2.1.0",
+ "rehype-autolink-headings": "~6.1.1",
+ "rehype-ignore": "^1.0.1",
+ "rehype-prism-plus": "~1.5.0",
+ "rehype-raw": "^6.1.1",
+ "rehype-rewrite": "~3.0.6",
+ "rehype-slug": "~5.1.0",
+ "remark-gfm": "~3.0.1",
+ "unist-util-visit": "^4.1.0"
+ }
+ },
"@vitejs/plugin-react-swc": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.2.0.tgz",
@@ -4299,12 +5178,22 @@
"resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
"integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="
},
+ "bcp-47-match": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz",
+ "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ=="
+ },
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
},
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
+ },
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
@@ -4343,6 +5232,11 @@
"integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==",
"dev": true
},
+ "ccount": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
+ "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="
+ },
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -4436,6 +5330,11 @@
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg=="
},
+ "css-selector-parser": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz",
+ "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g=="
+ },
"css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
@@ -4506,6 +5405,11 @@
"resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw=="
},
+ "direction": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz",
+ "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="
+ },
"dlv": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
@@ -4672,6 +5576,11 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
+ "github-slugger": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
+ "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="
+ },
"glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -4705,11 +5614,130 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
},
+ "hast-util-from-parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz",
+ "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "@types/unist": "^2.0.0",
+ "hastscript": "^7.0.0",
+ "property-information": "^6.0.0",
+ "vfile": "^5.0.0",
+ "vfile-location": "^4.0.0",
+ "web-namespaces": "^2.0.0"
+ },
+ "dependencies": {
+ "hast-util-parse-selector": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
+ "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==",
+ "requires": {
+ "@types/hast": "^2.0.0"
+ }
+ },
+ "hastscript": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz",
+ "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-parse-selector": "^3.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0"
+ }
+ }
+ }
+ },
+ "hast-util-has-property": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz",
+ "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg=="
+ },
+ "hast-util-heading-rank": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-2.1.1.tgz",
+ "integrity": "sha512-iAuRp+ESgJoRFJbSyaqsfvJDY6zzmFoEnL1gtz1+U8gKtGGj1p0CVlysuUAUjq95qlZESHINLThwJzNGmgGZxA==",
+ "requires": {
+ "@types/hast": "^2.0.0"
+ }
+ },
+ "hast-util-is-element": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz",
+ "integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "@types/unist": "^2.0.0"
+ }
+ },
"hast-util-parse-selector": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
"integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ=="
},
+ "hast-util-raw": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz",
+ "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "@types/parse5": "^6.0.0",
+ "hast-util-from-parse5": "^7.0.0",
+ "hast-util-to-parse5": "^7.0.0",
+ "html-void-elements": "^2.0.0",
+ "parse5": "^6.0.0",
+ "unist-util-position": "^4.0.0",
+ "unist-util-visit": "^4.0.0",
+ "vfile": "^5.0.0",
+ "web-namespaces": "^2.0.0",
+ "zwitch": "^2.0.0"
+ }
+ },
+ "hast-util-select": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-5.0.5.tgz",
+ "integrity": "sha512-QQhWMhgTFRhCaQdgTKzZ5g31GLQ9qRb1hZtDPMqQaOhpLBziWcshUS0uCR5IJ0U1jrK/mxg35fmcq+Dp/Cy2Aw==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "@types/unist": "^2.0.0",
+ "bcp-47-match": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "css-selector-parser": "^1.0.0",
+ "direction": "^2.0.0",
+ "hast-util-has-property": "^2.0.0",
+ "hast-util-to-string": "^2.0.0",
+ "hast-util-whitespace": "^2.0.0",
+ "not": "^0.1.0",
+ "nth-check": "^2.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "unist-util-visit": "^4.0.0",
+ "zwitch": "^2.0.0"
+ }
+ },
+ "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",
+ "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "web-namespaces": "^2.0.0",
+ "zwitch": "^2.0.0"
+ }
+ },
+ "hast-util-to-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz",
+ "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==",
+ "requires": {
+ "@types/hast": "^2.0.0"
+ }
+ },
"hast-util-whitespace": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz",
@@ -4767,6 +5795,11 @@
}
}
},
+ "html-void-elements": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz",
+ "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A=="
+ },
"inline-style-parser": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
@@ -4880,6 +5913,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
+ "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",
@@ -4897,6 +5935,11 @@
"highlight.js": "~10.7.0"
}
},
+ "markdown-table": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
+ "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw=="
+ },
"mdast-util-definitions": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz",
@@ -4907,6 +5950,24 @@
"unist-util-visit": "^4.0.0"
}
},
+ "mdast-util-find-and-replace": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz",
+ "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "escape-string-regexp": "^5.0.0",
+ "unist-util-is": "^5.0.0",
+ "unist-util-visit-parents": "^5.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="
+ }
+ }
+ },
"mdast-util-from-markdown": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.0.tgz",
@@ -4926,6 +5987,79 @@
"uvu": "^0.5.0"
}
},
+ "mdast-util-gfm": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz",
+ "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==",
+ "requires": {
+ "mdast-util-from-markdown": "^1.0.0",
+ "mdast-util-gfm-autolink-literal": "^1.0.0",
+ "mdast-util-gfm-footnote": "^1.0.0",
+ "mdast-util-gfm-strikethrough": "^1.0.0",
+ "mdast-util-gfm-table": "^1.0.0",
+ "mdast-util-gfm-task-list-item": "^1.0.0",
+ "mdast-util-to-markdown": "^1.0.0"
+ }
+ },
+ "mdast-util-gfm-autolink-literal": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz",
+ "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "ccount": "^2.0.0",
+ "mdast-util-find-and-replace": "^2.0.0",
+ "micromark-util-character": "^1.0.0"
+ }
+ },
+ "mdast-util-gfm-footnote": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz",
+ "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-markdown": "^1.3.0",
+ "micromark-util-normalize-identifier": "^1.0.0"
+ }
+ },
+ "mdast-util-gfm-strikethrough": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz",
+ "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-markdown": "^1.3.0"
+ }
+ },
+ "mdast-util-gfm-table": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz",
+ "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "markdown-table": "^3.0.0",
+ "mdast-util-from-markdown": "^1.0.0",
+ "mdast-util-to-markdown": "^1.3.0"
+ }
+ },
+ "mdast-util-gfm-task-list-item": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz",
+ "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-to-markdown": "^1.3.0"
+ }
+ },
+ "mdast-util-phrasing": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz",
+ "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "unist-util-is": "^5.0.0"
+ }
+ },
"mdast-util-to-hast": {
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz",
@@ -4941,6 +6075,21 @@
"unist-util-visit": "^4.0.0"
}
},
+ "mdast-util-to-markdown": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz",
+ "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "@types/unist": "^2.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-phrasing": "^3.0.0",
+ "mdast-util-to-string": "^3.0.0",
+ "micromark-util-decode-string": "^1.0.0",
+ "unist-util-visit": "^4.0.0",
+ "zwitch": "^2.0.0"
+ }
+ },
"mdast-util-to-string": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.1.1.tgz",
@@ -5002,6 +6151,92 @@
"uvu": "^0.5.0"
}
},
+ "micromark-extension-gfm": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz",
+ "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==",
+ "requires": {
+ "micromark-extension-gfm-autolink-literal": "^1.0.0",
+ "micromark-extension-gfm-footnote": "^1.0.0",
+ "micromark-extension-gfm-strikethrough": "^1.0.0",
+ "micromark-extension-gfm-table": "^1.0.0",
+ "micromark-extension-gfm-tagfilter": "^1.0.0",
+ "micromark-extension-gfm-task-list-item": "^1.0.0",
+ "micromark-util-combine-extensions": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "micromark-extension-gfm-autolink-literal": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz",
+ "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==",
+ "requires": {
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-sanitize-uri": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "micromark-extension-gfm-footnote": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz",
+ "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==",
+ "requires": {
+ "micromark-core-commonmark": "^1.0.0",
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-normalize-identifier": "^1.0.0",
+ "micromark-util-sanitize-uri": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ }
+ },
+ "micromark-extension-gfm-strikethrough": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz",
+ "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==",
+ "requires": {
+ "micromark-util-chunked": "^1.0.0",
+ "micromark-util-classify-character": "^1.0.0",
+ "micromark-util-resolve-all": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ }
+ },
+ "micromark-extension-gfm-table": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz",
+ "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==",
+ "requires": {
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ }
+ },
+ "micromark-extension-gfm-tagfilter": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz",
+ "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==",
+ "requires": {
+ "micromark-util-types": "^1.0.0"
+ }
+ },
+ "micromark-extension-gfm-task-list-item": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz",
+ "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==",
+ "requires": {
+ "micromark-factory-space": "^1.0.0",
+ "micromark-util-character": "^1.0.0",
+ "micromark-util-symbol": "^1.0.0",
+ "micromark-util-types": "^1.0.0",
+ "uvu": "^0.5.0"
+ }
+ },
"micromark-factory-destination": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz",
@@ -5217,6 +6452,19 @@
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
"dev": true
},
+ "not": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz",
+ "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA=="
+ },
+ "nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "requires": {
+ "boolbase": "^1.0.0"
+ }
+ },
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -5248,6 +6496,16 @@
}
}
},
+ "parse-numeric-range": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz",
+ "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ=="
+ },
+ "parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
+ },
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -5510,6 +6768,190 @@
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
+ "rehype-attr": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/rehype-attr/-/rehype-attr-2.1.4.tgz",
+ "integrity": "sha512-iAeaL5JyF4XxkcvWzpi/0SAF7iV7qOTaHS56tJuEsXziQc3+PEmMn65kV8OFgbO9mRVY7J1fRC/aLvot1PsNkg==",
+ "requires": {
+ "unified": "~10.1.1",
+ "unist-util-visit": "~4.1.0"
+ }
+ },
+ "rehype-autolink-headings": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-6.1.1.tgz",
+ "integrity": "sha512-NMYzZIsHM3sA14nC5rAFuUPIOfg+DFmf9EY1YMhaNlB7+3kK/ZlE6kqPfuxr1tsJ1XWkTrMtMoyHosU70d35mA==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "extend": "^3.0.0",
+ "hast-util-has-property": "^2.0.0",
+ "hast-util-heading-rank": "^2.0.0",
+ "hast-util-is-element": "^2.0.0",
+ "unified": "^10.0.0",
+ "unist-util-visit": "^4.0.0"
+ }
+ },
+ "rehype-ignore": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/rehype-ignore/-/rehype-ignore-1.0.5.tgz",
+ "integrity": "sha512-JQXS5eDwXaYKwB8JEYFJJA/YvGi0sSNUOYuiURMtuPTg8tuWHFB91JMYLbImH1FyvyGQM4fIBqNMAPB50WR2Bw==",
+ "requires": {
+ "hast-util-select": "^5.0.5",
+ "unified": "^10.1.2",
+ "unist-util-visit": "^4.1.2"
+ }
+ },
+ "rehype-parse": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.4.tgz",
+ "integrity": "sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "hast-util-from-parse5": "^7.0.0",
+ "parse5": "^6.0.0",
+ "unified": "^10.0.0"
+ }
+ },
+ "rehype-prism-plus": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/rehype-prism-plus/-/rehype-prism-plus-1.5.1.tgz",
+ "integrity": "sha512-mowYefSfrIkMMxkb0fwuEXlvc5nA9b1vQ6mzujM81Qx28RI0mo7jCHsBZ2tJ4eIJKXdFn+EdPkZZBGB10K02vg==",
+ "requires": {
+ "hast-util-to-string": "^2.0.0",
+ "parse-numeric-range": "^1.3.0",
+ "refractor": "^4.7.0",
+ "rehype-parse": "^8.0.2",
+ "unist-util-filter": "^4.0.0",
+ "unist-util-visit": "^4.0.0"
+ },
+ "dependencies": {
+ "character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="
+ },
+ "character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="
+ },
+ "hast-util-parse-selector": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz",
+ "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==",
+ "requires": {
+ "@types/hast": "^2.0.0"
+ }
+ },
+ "hastscript": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz",
+ "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-parse-selector": "^3.0.0",
+ "property-information": "^6.0.0",
+ "space-separated-tokens": "^2.0.0"
+ }
+ },
+ "is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="
+ },
+ "is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "requires": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ }
+ },
+ "is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="
+ },
+ "is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="
+ },
+ "parse-entities": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz",
+ "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==",
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "character-entities": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ }
+ },
+ "refractor": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-4.8.1.tgz",
+ "integrity": "sha512-/fk5sI0iTgFYlmVGYVew90AoYnNMP6pooClx/XKqyeeCQXrL0Kvgn8V0VEht5ccdljbzzF1i3Q213gcntkRExg==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "@types/prismjs": "^1.0.0",
+ "hastscript": "^7.0.0",
+ "parse-entities": "^4.0.0"
+ }
+ }
+ }
+ },
+ "rehype-raw": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz",
+ "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "hast-util-raw": "^7.2.0",
+ "unified": "^10.0.0"
+ }
+ },
+ "rehype-rewrite": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/rehype-rewrite/-/rehype-rewrite-3.0.6.tgz",
+ "integrity": "sha512-REDTNCvsKcAazy8IQWzKp66AhSUDSOIKssSCqNqCcT9sN7JCwAAm3mWGTUdUzq80ABuy8d0D6RBwbnewu1aY1g==",
+ "requires": {
+ "hast-util-select": "~5.0.1",
+ "unified": "~10.1.1",
+ "unist-util-visit": "~4.1.0"
+ }
+ },
+ "rehype-slug": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-5.1.0.tgz",
+ "integrity": "sha512-Gf91dJoXneiorNEnn+Phx97CO7oRMrpi+6r155tTxzGuLtm+QrI4cTwCa9e1rtePdL4i9tSO58PeSS6HWfgsiw==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "github-slugger": "^2.0.0",
+ "hast-util-has-property": "^2.0.0",
+ "hast-util-heading-rank": "^2.0.0",
+ "hast-util-to-string": "^2.0.0",
+ "unified": "^10.0.0",
+ "unist-util-visit": "^4.0.0"
+ }
+ },
+ "remark-gfm": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz",
+ "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==",
+ "requires": {
+ "@types/mdast": "^3.0.0",
+ "mdast-util-gfm": "^2.0.0",
+ "micromark-extension-gfm": "^2.0.0",
+ "unified": "^10.0.0"
+ }
+ },
"remark-parse": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.1.tgz",
@@ -5722,6 +7164,16 @@
"vfile": "^5.0.0"
}
},
+ "unist-util-filter": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/unist-util-filter/-/unist-util-filter-4.0.1.tgz",
+ "integrity": "sha512-RynicUM/vbOSTSiUK+BnaK9XMfmQUh6gyi7L6taNgc7FIf84GukXVV3ucGzEN/PhUUkdP5hb1MmXc+3cvPUm5Q==",
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "unist-util-is": "^5.0.0",
+ "unist-util-visit-parents": "^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",
@@ -5819,6 +7271,15 @@
"vfile-message": "^3.0.0"
}
},
+ "vfile-location": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz",
+ "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==",
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "vfile": "^5.0.0"
+ }
+ },
"vfile-message": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz",
@@ -5849,6 +7310,11 @@
"fs-extra": "^10.0.0"
}
},
+ "web-namespaces": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
+ "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="
+ },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -5859,6 +7325,11 @@
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
"dev": true
+ },
+ "zwitch": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
+ "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="
}
}
}
diff --git a/extension/react-app/package.json b/extension/react-app/package.json
index 4bedb813..704f520a 100644
--- a/extension/react-app/package.json
+++ b/extension/react-app/package.json
@@ -12,12 +12,12 @@
"@styled-icons/heroicons-outline": "^10.47.0",
"@styled-icons/heroicons-solid": "^10.47.0",
"@types/vscode-webview": "^1.57.1",
+ "@uiw/react-markdown-preview": "^4.1.13",
"downshift": "^7.6.0",
"posthog-js": "^1.58.0",
"prismjs": "^1.29.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-markdown": "^8.0.5",
"react-redux": "^8.0.5",
"react-switch": "^7.0.0",
"react-syntax-highlighter": "^15.5.0",
diff --git a/extension/react-app/public/vite.svg b/extension/react-app/public/vite.svg
deleted file mode 100644
index e7b8dfb1..00000000
--- a/extension/react-app/public/vite.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg> \ No newline at end of file
diff --git a/extension/react-app/src/App.tsx b/extension/react-app/src/App.tsx
index 8785f88f..aa462171 100644
--- a/extension/react-app/src/App.tsx
+++ b/extension/react-app/src/App.tsx
@@ -1,11 +1,8 @@
import DebugPanel from "./components/DebugPanel";
-import MainTab from "./tabs/main";
-import WelcomeTab from "./tabs/welcome";
-import ChatTab from "./tabs/chat";
-import GUI from "./tabs/gui";
+import GUI from "./pages/gui";
import { createContext } from "react";
import useContinueGUIProtocol from "./hooks/useWebsocket";
-import ContinueGUIClientProtocol from "./hooks/useContinueGUIProtocol";
+import ContinueGUIClientProtocol from "./hooks/ContinueGUIClientProtocol";
export const GUIClientContext = createContext<
ContinueGUIClientProtocol | undefined
@@ -16,17 +13,7 @@ function App() {
return (
<GUIClientContext.Provider value={client}>
- <DebugPanel
- tabs={[
- {
- element: <GUI />,
- title: "GUI",
- },
- // { element: <MainTab />, title: "Debug Panel" },
- // { element: <WelcomeTab />, title: "Welcome" },
- // { element: <ChatTab />, title: "Chat" },
- ]}
- />
+ <DebugPanel tabs={[{ element: <GUI />, title: "GUI" }]} />
</GUIClientContext.Provider>
);
}
diff --git a/extension/react-app/src/TestPage.tsx b/extension/react-app/src/TestPage.tsx
deleted file mode 100644
index d104980b..00000000
--- a/extension/react-app/src/TestPage.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-
-const SideBySideDiv = styled.div`
- display: grid;
- grid-template-columns: 1fr 1fr;
- grid-template-rows: 1fr;
- grid-template-areas: "left right";
-`;
-
-const LeftDiv = styled.div`
- grid-area: left;
-`;
-
-const RightDiv = styled.div`
- grid-area: right;
-`;
-
-function TestPage() {
- return (
- <div>
- <h1>Continue</h1>
- <SideBySideDiv>
- <LeftDiv>
- <h2>Left</h2>
- </LeftDiv>
- <RightDiv>
- <h2>Right</h2>
- </RightDiv>
- </SideBySideDiv>
- </div>
- );
-}
diff --git a/extension/react-app/src/assets/Hubot-Sans.woff2 b/extension/react-app/src/assets/Hubot-Sans.woff2
deleted file mode 100644
index 5089fc47..00000000
--- a/extension/react-app/src/assets/Hubot-Sans.woff2
+++ /dev/null
Binary files differ
diff --git a/extension/react-app/src/assets/Mona-Sans.woff2 b/extension/react-app/src/assets/Mona-Sans.woff2
deleted file mode 100644
index 8208a500..00000000
--- a/extension/react-app/src/assets/Mona-Sans.woff2
+++ /dev/null
Binary files differ
diff --git a/extension/react-app/src/assets/react.svg b/extension/react-app/src/assets/react.svg
deleted file mode 100644
index 6c87de9b..00000000
--- a/extension/react-app/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg> \ No newline at end of file
diff --git a/extension/react-app/src/components/CodeMultiselect.tsx b/extension/react-app/src/components/CodeMultiselect.tsx
deleted file mode 100644
index c0ab9400..00000000
--- a/extension/react-app/src/components/CodeMultiselect.tsx
+++ /dev/null
@@ -1,276 +0,0 @@
-import React, { useEffect, useState } from "react";
-import styled from "styled-components";
-import { Button, buttonColor, defaultBorderRadius, secondaryDark } from ".";
-import { useSelector } from "react-redux";
-import {
- selectDebugContext,
- selectAllRangesInFiles,
- selectRangesMask,
-} from "../redux/selectors/debugContextSelectors";
-import "../highlight/dark.min.css";
-import hljs from "highlight.js";
-import { postVscMessage } from "../vscode";
-import { RootStore } from "../redux/store";
-import { useDispatch } from "react-redux";
-import {
- addRangeInFile,
- deleteRangeInFileAt,
- toggleSelectionAt,
- updateFileSystem,
-} from "../redux/slices/debugContexSlice";
-import { RangeInFile } from "../../../src/client";
-import { readRangeInVirtualFileSystem } from "../util";
-
-//#region Styled Components
-
-const MultiSelectContainer = styled.div`
- border-radius: ${defaultBorderRadius};
- padding: 4px;
- display: flex;
- flex-direction: column;
- gap: 4px;
-`;
-
-const MultiSelectHeader = styled.div`
- display: flex;
- justify-content: space-between;
- align-items: left;
- border-bottom: 1px solid gray;
- padding-left: 4px;
- padding-right: 4px;
- & p {
- overflow-wrap: break-word;
- word-wrap: break-word;
- -ms-wrap-flow: break-word;
- overflow: hidden;
- }
-`;
-
-const MultiSelectOption = styled.div`
- border-radius: ${defaultBorderRadius};
- padding-top: 4px;
- cursor: pointer;
- background-color: ${secondaryDark};
-`;
-
-const DeleteSelectedRangeButton = styled(Button)`
- align-self: right;
- padding: 0px;
- margin-top: 0;
- aspect-ratio: 1/1;
- height: 28px;
-`;
-
-const ToggleHighlightButton = styled(Button)`
- display: grid;
- justify-content: center;
- align-items: center;
- grid-template-columns: 30px 1fr;
- margin-left: 20px;
- order: 1;
- width: fit-content;
-`;
-
-//#endregion
-
-//#region Path Formatting
-
-const filenameToLanguageMap: any = {
- py: "python",
- js: "javascript",
- ts: "typescript",
- html: "html",
- css: "css",
- java: "java",
- c: "c",
- cpp: "cpp",
- cs: "csharp",
- go: "go",
- rb: "ruby",
- rs: "rust",
- swift: "swift",
- php: "php",
- scala: "scala",
- kt: "kotlin",
- dart: "dart",
- hs: "haskell",
- lua: "lua",
- pl: "perl",
- r: "r",
- sql: "sql",
- vb: "vb",
- xml: "xml",
- yaml: "yaml",
-};
-
-function filenameToLanguage(filename: string): string {
- const extension = filename.split(".").pop();
- if (extension === undefined) {
- return "";
- }
- return filenameToLanguageMap[extension] || "";
-}
-
-function formatPathRelativeToWorkspace(
- path: string,
- workspacePath: string | undefined
-) {
- if (workspacePath === undefined) {
- return path;
- }
- if (path.startsWith(workspacePath)) {
- return path.substring(workspacePath.length + 1);
- } else {
- return path;
- }
-}
-
-function formatFileRange(
- rangeInFile: RangeInFile,
- workspacePath: string | undefined
-) {
- return `${formatPathRelativeToWorkspace(
- rangeInFile.filepath,
- workspacePath
- )} (lines ${rangeInFile.range.start.line + 1}-${
- rangeInFile.range.end.line + 1
- })`;
- // +1 because VS Code Ranges are 0-indexed
-}
-
-//#endregion
-
-function CodeMultiselect(props: {}) {
- // State
- const [highlightLocked, setHighlightLocked] = useState(true);
-
- // Redux
- const dispatch = useDispatch();
- const workspacePath = useSelector(
- (state: RootStore) => state.config.workspacePath
- );
- const debugContext = useSelector(selectDebugContext);
- const rangesInFiles = useSelector(selectAllRangesInFiles);
- const rangesInFilesMask = useSelector(selectRangesMask);
-
- useEffect(() => {
- let eventListener = (event: any) => {
- switch (event.data.type) {
- case "highlightedCode":
- if (!highlightLocked) {
- dispatch(
- addRangeInFile({
- rangeInFile: event.data.rangeInFile,
- canUpdateLast: true,
- })
- );
- dispatch(updateFileSystem(event.data.filesystem));
- }
- break;
- case "findSuspiciousCode":
- for (let c of event.data.codeLocations) {
- dispatch(addRangeInFile({ rangeInFile: c, canUpdateLast: false }));
- }
- dispatch(updateFileSystem(event.data.filesystem));
- postVscMessage("listTenThings", { debugContext });
- break;
- }
- };
- window.addEventListener("message", eventListener);
- return () => window.removeEventListener("message", eventListener);
- }, [debugContext, highlightLocked]);
-
- useEffect(() => {
- hljs.highlightAll();
- }, [rangesInFiles]);
-
- return (
- <MultiSelectContainer>
- {rangesInFiles.map((range: RangeInFile, index: number) => {
- return (
- <MultiSelectOption
- key={index}
- style={{
- border: `1px solid ${
- rangesInFilesMask[index] ? buttonColor : "gray"
- }`,
- }}
- onClick={() => {
- dispatch(toggleSelectionAt(index));
- }}
- >
- <MultiSelectHeader>
- <p style={{ margin: "4px" }}>
- {formatFileRange(range, workspacePath)}
- </p>
- <DeleteSelectedRangeButton
- onClick={() => dispatch(deleteRangeInFileAt(index))}
- >
- x
- </DeleteSelectedRangeButton>
- </MultiSelectHeader>
- <pre>
- <code
- className={"language-" + filenameToLanguage(range.filepath)}
- >
- {readRangeInVirtualFileSystem(range, debugContext.filesystem)}
- </code>
- </pre>
- </MultiSelectOption>
- );
- })}
- {rangesInFiles.length === 0 && (
- <>
- <p>Highlight relevant code in the editor.</p>
- </>
- )}
- <ToggleHighlightButton
- onClick={() => {
- setHighlightLocked(!highlightLocked);
- }}
- >
- {highlightLocked ? (
- <>
- <svg
- xmlns="http://www.w3.org/2000/svg"
- width="20px"
- fill="none"
- viewBox="0 0 24 24"
- strokeWidth="1.5"
- stroke="currentColor"
- className="w-6 h-6"
- >
- <path
- strokeLinecap="round"
- strokeLinejoin="round"
- d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"
- />
- </svg>{" "}
- Enable Highlight
- </>
- ) : (
- <>
- <svg
- xmlns="http://www.w3.org/2000/svg"
- width="20px"
- fill="none"
- viewBox="0 0 24 24"
- strokeWidth="1.5"
- stroke="currentColor"
- className="w-6 h-6"
- >
- <path
- strokeLinecap="round"
- strokeLinejoin="round"
- d="M13.5 10.5V6.75a4.5 4.5 0 119 0v3.75M3.75 21.75h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H3.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"
- />
- </svg>{" "}
- Disable Highlight
- </>
- )}
- </ToggleHighlightButton>
- </MultiSelectContainer>
- );
-}
-
-export default CodeMultiselect;
diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx
index e6632360..f327e3a3 100644
--- a/extension/react-app/src/components/ComboBox.tsx
+++ b/extension/react-app/src/components/ComboBox.tsx
@@ -1,30 +1,20 @@
-import React, {
- useCallback,
- useEffect,
- useImperativeHandle,
- useState,
-} from "react";
+import React, { useEffect, useImperativeHandle, useState } from "react";
import { useCombobox } from "downshift";
import styled from "styled-components";
import {
- buttonColor,
defaultBorderRadius,
lightGray,
secondaryDark,
vscBackground,
+ vscForeground,
} from ".";
import CodeBlock from "./CodeBlock";
-import { RangeInFile } from "../../../src/client";
import PillButton from "./PillButton";
import HeaderButtonWithText from "./HeaderButtonWithText";
-import {
- Trash,
- LockClosed,
- LockOpen,
- Plus,
- DocumentPlus,
-} from "@styled-icons/heroicons-outline";
+import { DocumentPlus } from "@styled-icons/heroicons-outline";
import { HighlightedRangeContext } from "../../../schema/FullState";
+import { postVscMessage } from "../vscode";
+import { getMetaKeyLabel } from "../util";
// #region styled components
const mainInputFontSize = 13;
@@ -48,21 +38,6 @@ const EmptyPillDiv = styled.div`
}
`;
-const ContextDropdown = styled.div`
- position: absolute;
- padding: 4px;
- width: calc(100% - 16px - 8px);
- background-color: ${secondaryDark};
- color: white;
- border-bottom-right-radius: ${defaultBorderRadius};
- border-bottom-left-radius: ${defaultBorderRadius};
- /* border: 1px solid white; */
- border-top: none;
- margin: 8px;
- outline: 1px solid orange;
- z-index: 5;
-`;
-
const MainTextInput = styled.textarea`
resize: none;
@@ -74,7 +49,7 @@ const MainTextInput = styled.textarea`
height: auto;
width: 100%;
background-color: ${secondaryDark};
- color: white;
+ color: ${vscForeground};
z-index: 1;
border: 1px solid transparent;
@@ -97,14 +72,15 @@ const Ul = styled.ul<{
position: absolute;
background: ${vscBackground};
background-color: ${secondaryDark};
- color: white;
+ color: ${vscForeground};
max-height: ${UlMaxHeight}px;
+ width: calc(100% - 16px);
overflow-y: scroll;
overflow-x: hidden;
padding: 0;
${({ hidden }) => hidden && "display: none;"}
border-radius: ${defaultBorderRadius};
- border: 0.5px solid gray;
+ outline: 0.5px solid gray;
z-index: 2;
// Get rid of scrollbar and its padding
scrollbar-width: none;
@@ -120,6 +96,7 @@ const Li = styled.li<{
selected: boolean;
isLastItem: boolean;
}>`
+ background-color: ${secondaryDark};
${({ highlighted }) => highlighted && "background: #ff000066;"}
${({ selected }) => selected && "font-weight: bold;"}
padding: 0.5rem 0.75rem;
@@ -149,10 +126,6 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
// The position of the current command you are typing now, so the one that will be appended to history once you press enter
const [positionInHistory, setPositionInHistory] = React.useState<number>(0);
const [items, setItems] = React.useState(props.items);
- const [hoveringButton, setHoveringButton] = React.useState(false);
- const [hoveringContextDropdown, setHoveringContextDropdown] =
- React.useState(false);
- const [pinned, setPinned] = useState(false);
const [highlightedCodeSections, setHighlightedCodeSections] = React.useState(
props.highlightedCodeSections || []
);
@@ -180,6 +153,27 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
useImperativeHandle(ref, () => downshiftProps, [downshiftProps]);
+ const [metaKeyPressed, setMetaKeyPressed] = useState(false);
+ const [focused, setFocused] = useState(false);
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === "Meta") {
+ setMetaKeyPressed(true);
+ }
+ };
+ const handleKeyUp = (e: KeyboardEvent) => {
+ if (e.key === "Meta") {
+ setMetaKeyPressed(false);
+ }
+ };
+ window.addEventListener("keydown", handleKeyDown);
+ window.addEventListener("keyup", handleKeyUp);
+ return () => {
+ window.removeEventListener("keydown", handleKeyDown);
+ window.removeEventListener("keyup", handleKeyUp);
+ };
+ });
+
useEffect(() => {
if (!inputRef.current) {
return;
@@ -221,11 +215,19 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
)} */}
{highlightedCodeSections.map((section, idx) => (
<PillButton
+ warning={
+ section.range.contents.length > 4000 && section.editing
+ ? "Editing such a large range may be slow"
+ : undefined
+ }
+ onlyShowDelete={
+ highlightedCodeSections.length <= 1 || section.editing
+ }
editing={section.editing}
pinned={section.pinned}
index={idx}
- key={`${section.filepath}${idx}`}
- title={`${section.range.filepath} (${
+ key={`${section.display_name}${idx}`}
+ title={`${section.display_name} (${
section.range.range.start.line + 1
}-${section.range.range.end.line + 1})`}
onDelete={() => {
@@ -238,15 +240,6 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
return newSections;
});
}}
- onHover={(val: boolean) => {
- if (val) {
- setHoveringButton(val);
- } else {
- setTimeout(() => {
- setHoveringButton(val);
- }, 100);
- }
- }}
/>
))}
{props.highlightedCodeSections.length > 0 &&
@@ -256,11 +249,11 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
props.onToggleAddContext();
}}
>
- Highlight to Add Context
+ Highlight code section
</EmptyPillDiv>
) : (
<HeaderButtonWithText
- text="Add to Context"
+ text="Add more code to context"
onClick={() => {
props.onToggleAddContext();
}}
@@ -272,7 +265,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
<div className="flex px-2" ref={divRef} hidden={!downshiftProps.isOpen}>
<MainTextInput
disabled={props.disabled}
- placeholder="Ask a question, give instructions, or type '/' to see slash commands"
+ placeholder={`Ask a question, give instructions, or type '/' to see slash commands`}
{...getInputProps({
onChange: (e) => {
const target = e.target as HTMLTextAreaElement;
@@ -285,6 +278,13 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
// setShowContextDropdown(target.value.endsWith("@"));
},
+ onFocus: (e) => {
+ setFocused(true);
+ },
+ onBlur: (e) => {
+ setFocused(false);
+ postVscMessage("blurContinueInput", {});
+ },
onKeyDown: (event) => {
if (event.key === "Enter" && event.shiftKey) {
// Prevent Downshift's default 'Enter' behavior.
@@ -311,7 +311,6 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
) {
(event.nativeEvent as any).preventDownshiftDefault = true;
} else if (event.key === "ArrowUp") {
- console.log("OWJFOIJO");
if (positionInHistory == 0) return;
else if (
positionInHistory == history.length &&
@@ -340,6 +339,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
})}
showAbove={showAbove()}
ulHeightPixels={ulRef.current?.getBoundingClientRect().height || 0}
+ hidden={!downshiftProps.isOpen || items.length === 0}
>
{downshiftProps.isOpen &&
items.map((item, index) => (
@@ -357,28 +357,15 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
))}
</Ul>
</div>
- {/* <span className="text-trueGray-400 ml-auto m-auto text-xs text-right">
- Highlight code to include as context. Currently open file included by
- default. {highlightedCodeSections.length === 0 && ""}
- </span> */}
- <ContextDropdown
- onMouseEnter={() => {
- setHoveringContextDropdown(true);
- }}
- onMouseLeave={() => {
- setHoveringContextDropdown(false);
- }}
- hidden={true || (!hoveringContextDropdown && !hoveringButton)}
- >
- {highlightedCodeSections.map((section, idx) => (
- <>
- <p>{section.range.filepath}</p>
- <CodeBlock showCopy={false} key={idx}>
- {section.range.contents}
- </CodeBlock>
- </>
- ))}
- </ContextDropdown>
+ {highlightedCodeSections.length === 0 &&
+ (downshiftProps.inputValue?.startsWith("/edit") ||
+ (focused &&
+ metaKeyPressed &&
+ downshiftProps.inputValue?.length > 0)) && (
+ <div className="text-trueGray-400 pr-4 text-xs text-right">
+ Inserting at cursor
+ </div>
+ )}
</>
);
});
diff --git a/extension/react-app/src/components/InputAndButton.tsx b/extension/react-app/src/components/InputAndButton.tsx
index 0a8592f2..8019d014 100644
--- a/extension/react-app/src/components/InputAndButton.tsx
+++ b/extension/react-app/src/components/InputAndButton.tsx
@@ -1,6 +1,6 @@
import React, { useRef } from "react";
import styled from "styled-components";
-import { vscBackground } from ".";
+import { vscBackground, vscForeground } from ".";
interface InputAndButtonProps {
onUserInput: (input: string) => void;
@@ -16,7 +16,7 @@ const Input = styled.input`
padding: 0.5rem;
border: 1px solid white;
background-color: ${vscBackground};
- color: white;
+ color: ${vscForeground};
border-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
@@ -27,7 +27,7 @@ const Button = styled.button`
padding: 0.5rem;
border: 1px solid white;
background-color: ${vscBackground};
- color: white;
+ color: ${vscForeground};
border-radius: 4px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
@@ -35,8 +35,8 @@ const Button = styled.button`
cursor: pointer;
&:hover {
- background-color: white;
- color: black;
+ background-color: ${vscForeground};
+ color: ${vscBackground};
}
`;
diff --git a/extension/react-app/src/components/LoadingCover.tsx b/extension/react-app/src/components/LoadingCover.tsx
deleted file mode 100644
index a0f8f7a2..00000000
--- a/extension/react-app/src/components/LoadingCover.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-
-const StyledDiv = styled.div`
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100vh;
- background: linear-gradient(
- 101.79deg,
- #12887a 0%,
- #87245c 32%,
- #e12637 63%,
- #ffb215 100%
- );
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- z-index: 10;
-`;
-
-const StyledImg = styled.img`
- /* add your styles here */
-`;
-
-const StyledDiv2 = styled.div`
- width: 50%;
- height: 5px;
- background: white;
- margin-top: 20px;
-`;
-
-interface LoadingCoverProps {
- message: string;
- hidden?: boolean;
-}
-
-const LoadingCover = (props: LoadingCoverProps) => {
- return (
- <StyledDiv style={{ display: props.hidden ? "none" : "inherit" }}>
- <StyledImg src="continue.gif" alt="centered image" width="50%" />
- <StyledDiv2></StyledDiv2>
- <p>{props.message}</p>
- </StyledDiv>
- );
-};
-
-export default LoadingCover;
diff --git a/extension/react-app/src/components/Onboarding.tsx b/extension/react-app/src/components/Onboarding.tsx
new file mode 100644
index 00000000..231c1e93
--- /dev/null
+++ b/extension/react-app/src/components/Onboarding.tsx
@@ -0,0 +1,136 @@
+import { useSelector } from "react-redux";
+import { RootStore } from "../redux/store";
+import React, { useState, useEffect } from "react";
+import styled from "styled-components";
+import { ArrowLeft, ArrowRight } from "@styled-icons/heroicons-outline";
+import { defaultBorderRadius } from ".";
+import Loader from "./Loader";
+
+const StyledDiv = styled.div`
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: #1e1e1e;
+ z-index: 200;
+`;
+
+const StyledSpan = styled.span`
+ padding: 8px;
+ border-radius: ${defaultBorderRadius};
+ &:hover {
+ background-color: #ffffff33;
+ }
+ white-space: nowrap;
+`;
+
+const Onboarding = () => {
+ const [counter, setCounter] = useState(4);
+ const gifs = ["intro", "highlight", "question", "help"];
+ const topMessages = [
+ "Welcome!",
+ "Highlight code",
+ "Ask a question",
+ "Use /help to learn more",
+ ];
+
+ useEffect(() => {
+ const hasVisited = localStorage.getItem("hasVisited");
+ if (hasVisited) {
+ setCounter(4);
+ } else {
+ setCounter(0);
+ localStorage.setItem("hasVisited", "true");
+ }
+ }, []);
+
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ setLoading(true);
+ }, [counter]);
+
+ return (
+ <StyledDiv hidden={counter >= 4}>
+ <div
+ style={{
+ display: "grid",
+ justifyContent: "center",
+ alignItems: "center",
+ height: "100%",
+ textAlign: "center",
+ background: `linear-gradient(
+ 101.79deg,
+ #12887a66 0%,
+ #87245c66 32%,
+ #e1263766 63%,
+ #ffb21566 100%
+ )`,
+ paddingLeft: "16px",
+ paddingRight: "16px",
+ }}
+ >
+ <h1>{topMessages[counter]}</h1>
+ <div style={{ display: "flex", justifyContent: "center" }}>
+ {loading && (
+ <div style={{ margin: "auto", position: "absolute", zIndex: 0 }}>
+ <Loader />
+ </div>
+ )}
+ {counter % 2 === 0 ? (
+ <img
+ src={`https://github.com/continuedev/continue/blob/main/media/${gifs[counter]}.gif?raw=true`}
+ width="100%"
+ key={"even-gif"}
+ alt={topMessages[counter]}
+ onLoad={() => {
+ setLoading(false);
+ }}
+ style={{ zIndex: 1 }}
+ />
+ ) : (
+ <img
+ src={`https://github.com/continuedev/continue/blob/main/media/${gifs[counter]}.gif?raw=true`}
+ width="100%"
+ key={"odd-gif"}
+ alt={topMessages[counter]}
+ onLoad={() => {
+ setLoading(false);
+ }}
+ style={{ zIndex: 1 }}
+ />
+ )}
+ </div>
+ <p
+ style={{
+ paddingLeft: "50px",
+ paddingRight: "50px",
+ paddingBottom: "50px",
+ textAlign: "center",
+ cursor: "pointer",
+ whiteSpace: "nowrap",
+ }}
+ >
+ <StyledSpan
+ hidden={counter === 0}
+ onClick={() => setCounter((prev) => Math.max(prev - 1, 0))}
+ >
+ <ArrowLeft width="18px" strokeWidth="2px" /> Previous
+ </StyledSpan>
+ <span hidden={counter === 0}>{" | "}</span>
+ <StyledSpan onClick={() => setCounter((prev) => prev + 1)}>
+ {counter === 0
+ ? "Click to learn how to use Continue"
+ : counter === 3
+ ? "Get Started"
+ : "Next"}{" "}
+ <ArrowRight width="18px" strokeWidth="2px" />
+ </StyledSpan>
+ </p>
+ </div>
+ </StyledDiv>
+ );
+};
+
+export default Onboarding;
diff --git a/extension/react-app/src/components/PillButton.tsx b/extension/react-app/src/components/PillButton.tsx
index 31d98c0f..c24dba83 100644
--- a/extension/react-app/src/components/PillButton.tsx
+++ b/extension/react-app/src/components/PillButton.tsx
@@ -3,15 +3,19 @@ import styled from "styled-components";
import {
StyledTooltip,
defaultBorderRadius,
- lightGray,
secondaryDark,
+ vscForeground,
} from ".";
-import { Trash, PaintBrush, MapPin } from "@styled-icons/heroicons-outline";
+import {
+ Trash,
+ PaintBrush,
+ ExclamationTriangle,
+} from "@styled-icons/heroicons-outline";
import { GUIClientContext } from "../App";
const Button = styled.button`
border: none;
- color: white;
+ color: ${vscForeground};
background-color: ${secondaryDark};
border-radius: ${defaultBorderRadius};
padding: 8px;
@@ -28,10 +32,8 @@ const GridDiv = styled.div`
height: 100%;
display: grid;
grid-gap: 0;
- grid-template-columns: 1fr 1fr;
align-items: center;
border-radius: ${defaultBorderRadius};
- overflow: hidden;
background-color: ${secondaryDark};
`;
@@ -48,6 +50,21 @@ const ButtonDiv = styled.div<{ backgroundColor: string }>`
}
`;
+const CircleDiv = styled.div`
+ position: absolute;
+ top: -10px;
+ right: -10px;
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ background-color: red;
+ color: white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 2px;
+`;
+
interface PillButtonProps {
onHover?: (arg0: boolean) => void;
onDelete?: () => void;
@@ -55,6 +72,8 @@ interface PillButtonProps {
index: number;
editing: boolean;
pinned: boolean;
+ warning?: string;
+ onlyShowDelete?: boolean;
}
const PillButton = (props: PillButtonProps) => {
@@ -63,75 +82,102 @@ const PillButton = (props: PillButtonProps) => {
return (
<>
- <Button
- style={{
- position: "relative",
- borderColor: props.editing
- ? "#8800aa"
- : props.pinned
- ? "#ffff0099"
- : "transparent",
- borderWidth: "1px",
- borderStyle: "solid",
- }}
- onMouseEnter={() => {
- setIsHovered(true);
- if (props.onHover) {
- props.onHover(true);
- }
- }}
- onMouseLeave={() => {
- setIsHovered(false);
- if (props.onHover) {
- props.onHover(false);
- }
- }}
- >
- {isHovered && (
- <GridDiv>
- <ButtonDiv
- data-tooltip-id={`edit-${props.index}`}
- backgroundColor={"#8800aa55"}
- onClick={() => {
- client?.setEditingAtIndices([props.index]);
+ <div style={{ position: "relative" }}>
+ <Button
+ style={{
+ position: "relative",
+ borderColor: props.warning
+ ? "red"
+ : props.editing
+ ? "#8800aa"
+ : props.pinned
+ ? "#ffff0099"
+ : "transparent",
+ borderWidth: "1px",
+ borderStyle: "solid",
+ }}
+ onMouseEnter={() => {
+ setIsHovered(true);
+ if (props.onHover) {
+ props.onHover(true);
+ }
+ }}
+ onMouseLeave={() => {
+ setIsHovered(false);
+ if (props.onHover) {
+ props.onHover(false);
+ }
+ }}
+ >
+ {isHovered && (
+ <GridDiv
+ style={{
+ gridTemplateColumns: props.onlyShowDelete ? "1fr" : "1fr 1fr",
}}
>
- <PaintBrush style={{ margin: "auto" }} width="1.6em"></PaintBrush>
- </ButtonDiv>
+ {props.onlyShowDelete || (
+ <ButtonDiv
+ data-tooltip-id={`edit-${props.index}`}
+ backgroundColor={"#8800aa55"}
+ onClick={() => {
+ client?.setEditingAtIndices([props.index]);
+ }}
+ >
+ <PaintBrush
+ style={{ margin: "auto" }}
+ width="1.6em"
+ ></PaintBrush>
+ </ButtonDiv>
+ )}
- {/* <ButtonDiv
+ {/* <ButtonDiv
data-tooltip-id={`pin-${props.index}`}
backgroundColor={"#ffff0055"}
onClick={() => {
client?.setPinnedAtIndices([props.index]);
}}
- >
+ >
<MapPin style={{ margin: "auto" }} width="1.6em"></MapPin>
</ButtonDiv> */}
- <StyledTooltip id={`pin-${props.index}`}>
- Edit this range
+ <StyledTooltip id={`pin-${props.index}`}>
+ Edit this range
+ </StyledTooltip>
+ <ButtonDiv
+ data-tooltip-id={`delete-${props.index}`}
+ backgroundColor={"#cc000055"}
+ onClick={() => {
+ if (props.onDelete) {
+ props.onDelete();
+ }
+ }}
+ >
+ <Trash style={{ margin: "auto" }} width="1.6em"></Trash>
+ </ButtonDiv>
+ </GridDiv>
+ )}
+ {props.title}
+ </Button>
+ <StyledTooltip id={`edit-${props.index}`}>
+ {props.editing
+ ? "Editing this section (with entire file as context)"
+ : "Edit this section"}
+ </StyledTooltip>
+ <StyledTooltip id={`delete-${props.index}`}>Delete</StyledTooltip>
+ {props.warning && (
+ <>
+ <CircleDiv data-tooltip-id={`circle-div-${props.title}`}>
+ <ExclamationTriangle
+ style={{ margin: "auto" }}
+ width="1.0em"
+ strokeWidth={2}
+ />
+ </CircleDiv>
+ <StyledTooltip id={`circle-div-${props.title}`}>
+ {props.warning}
</StyledTooltip>
- <ButtonDiv
- data-tooltip-id={`delete-${props.index}`}
- backgroundColor={"#cc000055"}
- onClick={() => {
- if (props.onDelete) {
- props.onDelete();
- }
- }}
- >
- <Trash style={{ margin: "auto" }} width="1.6em"></Trash>
- </ButtonDiv>
- </GridDiv>
+ </>
)}
- {props.title}
- </Button>
- <StyledTooltip id={`edit-${props.index}`}>
- {props.editing
- ? "Editing this range (with rest of file as context)"
- : "Edit this range"}
- </StyledTooltip>
- <StyledTooltip id={`delete-${props.index}`}>Delete</StyledTooltip>
+ </div>
</>
);
};
diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index d480c565..bc8665fd 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useRef, useState } from "react";
+import { useContext, useEffect, useRef, useState } from "react";
import styled, { keyframes } from "styled-components";
import {
appear,
@@ -6,18 +6,21 @@ import {
secondaryDark,
vscBackground,
vscBackgroundTransparent,
+ vscForeground,
} from ".";
import {
ChevronDown,
ChevronRight,
ArrowPath,
XMark,
+ MagnifyingGlass,
} from "@styled-icons/heroicons-outline";
import { StopCircle } from "@styled-icons/heroicons-solid";
import { HistoryNode } from "../../../schema/HistoryNode";
-import ReactMarkdown from "react-markdown";
import HeaderButtonWithText from "./HeaderButtonWithText";
-import CodeBlock from "./CodeBlock";
+import MarkdownPreview from "@uiw/react-markdown-preview";
+import { getMetaKeyLabel, isMetaEquivalentKeyPressed } from "../util";
+import { GUIClientContext } from "../App";
interface StepContainerProps {
historyNode: HistoryNode;
@@ -31,6 +34,7 @@ interface StepContainerProps {
onToggle: () => void;
isFirst: boolean;
isLast: boolean;
+ index: number;
}
// #region styled components
@@ -38,7 +42,6 @@ interface StepContainerProps {
const MainDiv = styled.div<{ stepDepth: number; inFuture: boolean }>`
opacity: ${(props) => (props.inFuture ? 0.3 : 1)};
animation: ${appear} 0.3s ease-in-out;
- /* padding-left: ${(props) => props.stepDepth * 20}px; */
overflow: hidden;
margin-left: 0px;
margin-right: 0px;
@@ -52,12 +55,7 @@ const StepContainerDiv = styled.div<{ open: boolean }>`
`;
const HeaderDiv = styled.div<{ error: boolean; loading: boolean }>`
- background-color: ${(props) =>
- props.error
- ? "#522"
- : props.loading
- ? vscBackgroundTransparent
- : vscBackground};
+ background-color: ${(props) => (props.error ? "#522" : vscBackground)};
display: grid;
grid-template-columns: 1fr auto auto;
grid-gap: 8px;
@@ -72,19 +70,6 @@ const ContentDiv = styled.div<{ isUserInput: boolean }>`
font-size: 13px;
`;
-const MarkdownPre = styled.pre`
- background-color: ${secondaryDark};
- padding: 10px;
- border-radius: ${defaultBorderRadius};
- border: 0.5px solid white;
-`;
-
-const StyledCode = styled.code`
- word-wrap: break-word;
- color: #f69292;
- background: transparent;
-`;
-
const gradient = keyframes`
0% {
background-position: 0px 0;
@@ -124,6 +109,33 @@ const GradientBorder = styled.div<{
background-size: 200% 200%;
`;
+const StyledMarkdownPreview = styled(MarkdownPreview)`
+ pre {
+ background-color: ${secondaryDark};
+ padding: 1px;
+ border-radius: ${defaultBorderRadius};
+ border: 0.5px solid white;
+ }
+
+ code {
+ color: #f78383;
+ word-wrap: break-word;
+ border-radius: ${defaultBorderRadius};
+ background-color: ${secondaryDark};
+ }
+
+ pre > code {
+ background-color: ${secondaryDark};
+ color: ${vscForeground};
+ }
+
+ background-color: ${vscBackground};
+ font-family: "Lexend", sans-serif;
+ font-size: 13px;
+ padding: 8px;
+ color: ${vscForeground};
+`;
+
// #endregion
function StepContainer(props: StepContainerProps) {
@@ -131,6 +143,7 @@ function StepContainer(props: StepContainerProps) {
const naturalLanguageInputRef = useRef<HTMLTextAreaElement>(null);
const userInputRef = useRef<HTMLInputElement>(null);
const isUserInput = props.historyNode.step.name === "UserInputStep";
+ const client = useContext(GUIClientContext);
useEffect(() => {
if (userInputRef?.current) {
@@ -158,7 +171,7 @@ function StepContainer(props: StepContainerProps) {
>
<StepContainerDiv open={props.open}>
<GradientBorder
- loading={props.historyNode.active as boolean | false}
+ loading={(props.historyNode.active as boolean) || false}
isFirst={props.isFirst}
isLast={props.isLast}
borderColor={
@@ -170,7 +183,7 @@ function StepContainer(props: StepContainerProps) {
}
className="overflow-hidden cursor-pointer"
onClick={(e) => {
- if (e.metaKey) {
+ if (isMetaEquivalentKeyPressed(e)) {
props.onToggleAll();
} else {
props.onToggle();
@@ -178,7 +191,7 @@ function StepContainer(props: StepContainerProps) {
}}
>
<HeaderDiv
- loading={props.historyNode.active as boolean | false}
+ loading={(props.historyNode.active as boolean) || false}
error={props.historyNode.observation?.error ? true : false}
>
<div className="m-2">
@@ -201,12 +214,27 @@ function StepContainer(props: StepContainerProps) {
</HeaderButton> */}
<>
+ {(props.historyNode.logs as any)?.length > 0 && (
+ <HeaderButtonWithText
+ text="Logs"
+ onClick={(e) => {
+ e.stopPropagation();
+ client?.showLogsAtIndex(props.index);
+ }}
+ >
+ <MagnifyingGlass size="1.4em" />
+ </HeaderButtonWithText>
+ )}
<HeaderButtonWithText
onClick={(e) => {
e.stopPropagation();
props.onDelete();
}}
- text={props.historyNode.active ? "Stop (⌘⌫)" : "Delete"}
+ text={
+ props.historyNode.active
+ ? `Stop (${getMetaKeyLabel()}⌫)`
+ : "Delete"
+ }
>
{props.historyNode.active ? (
<StopCircle size="1.6em" onClick={props.onDelete} />
@@ -242,31 +270,19 @@ function StepContainer(props: StepContainerProps) {
)}
{props.historyNode.observation?.error ? (
- <pre className="overflow-x-scroll">
- {props.historyNode.observation.error as string}
- </pre>
+ <details>
+ <summary>View Traceback</summary>
+ <pre className="overflow-x-scroll">
+ {props.historyNode.observation.error as string}
+ </pre>
+ </details>
) : (
- <ReactMarkdown
- key={1}
- className="overflow-x-scroll"
- components={{
- pre: ({ node, ...props }) => {
- return (
- <CodeBlock
- children={(props.children[0] as any).props.children[0]}
- />
- );
- },
- code: ({ node, ...props }) => {
- return <StyledCode children={props.children[0] as any} />;
- },
- ul: ({ node, ...props }) => {
- return <ul className="ml-0" {...props} />;
- },
+ <StyledMarkdownPreview
+ source={props.historyNode.step.description || ""}
+ wrapperElement={{
+ "data-color-mode": "dark",
}}
- >
- {props.historyNode.step.description as any}
- </ReactMarkdown>
+ />
)}
</ContentDiv>
</StepContainerDiv>
diff --git a/extension/react-app/src/components/TextDialog.tsx b/extension/react-app/src/components/TextDialog.tsx
index ea5727f0..cba3852d 100644
--- a/extension/react-app/src/components/TextDialog.tsx
+++ b/extension/react-app/src/components/TextDialog.tsx
@@ -1,7 +1,8 @@
// Write a component that displays a dialog box with a text field and a button.
import React, { useEffect, useState } from "react";
import styled from "styled-components";
-import { Button, buttonColor, secondaryDark, vscBackground } from ".";
+import { Button, secondaryDark, vscBackground, vscForeground } from ".";
+import { isMetaEquivalentKeyPressed } from "../util";
const ScreenCover = styled.div`
position: absolute;
@@ -20,13 +21,13 @@ const DialogContainer = styled.div`
`;
const Dialog = styled.div`
- background-color: white;
+ color: ${vscForeground};
+ background-color: ${vscBackground};
border-radius: 8px;
padding: 8px;
display: flex;
flex-direction: column;
- /* box-shadow: 0 0 10px 0 rgba(255, 255, 255, 0.5); */
- border: 2px solid ${buttonColor};
+ box-shadow: 0 0 10px 0 ${vscForeground};
width: fit-content;
margin: auto;
`;
@@ -37,14 +38,16 @@ const TextArea = styled.textarea`
padding: 8px;
outline: 1px solid black;
resize: none;
+ background-color: ${secondaryDark};
+ color: ${vscForeground};
&:focus {
- outline: 1px solid ${buttonColor};
+ outline: 1px solid ${vscForeground};
}
`;
const P = styled.p`
- color: black;
+ color: ${vscForeground};
margin: 8px auto;
`;
@@ -81,7 +84,11 @@ const TextDialog = (props: {
rows={10}
ref={textAreaRef}
onKeyDown={(e) => {
- if (e.key === "Enter" && e.metaKey && textAreaRef.current) {
+ if (
+ e.key === "Enter" &&
+ isMetaEquivalentKeyPressed(e) &&
+ textAreaRef.current
+ ) {
props.onEnter(textAreaRef.current.value);
setText("");
} else if (e.key === "Escape") {
diff --git a/extension/react-app/src/components/index.ts b/extension/react-app/src/components/index.ts
index 9ae0f097..cb5e7915 100644
--- a/extension/react-app/src/components/index.ts
+++ b/extension/react-app/src/components/index.ts
@@ -3,12 +3,16 @@ import styled, { keyframes } from "styled-components";
export const defaultBorderRadius = "5px";
export const lightGray = "rgb(100 100 100)";
-export const secondaryDark = "rgb(45 45 45)";
-export const vscBackground = "rgb(30 30 30)";
+// export const secondaryDark = "rgb(45 45 45)";
+// export const vscBackground = "rgb(30 30 30)";
export const vscBackgroundTransparent = "#1e1e1ede";
export const buttonColor = "rgb(113 28 59)";
export const buttonColorHover = "rgb(113 28 59 0.67)";
+export const secondaryDark = "var(--vscode-textBlockQuote-background)";
+export const vscBackground = "var(--vscode-editor-background)";
+export const vscForeground = "var(--vscode-editor-foreground)";
+
export const Button = styled.button`
padding: 10px 12px;
margin: 8px 0;
@@ -46,8 +50,8 @@ export const TextArea = styled.textarea`
resize: vertical;
padding: 4px;
- caret-color: white;
- color: white;
+ caret-color: ${vscForeground};
+ color: #{vscForeground};
&:focus {
outline: 1px solid ${buttonColor};
@@ -120,7 +124,7 @@ export const MainTextInput = styled.textarea`
border: 1px solid #ccc;
margin: 8px 8px;
background-color: ${vscBackground};
- color: white;
+ color: ${vscForeground};
outline: 1px solid orange;
resize: none;
`;
@@ -137,8 +141,9 @@ export const appear = keyframes`
`;
export const HeaderButton = styled.button<{ inverted: boolean | undefined }>`
- background-color: ${({ inverted }) => (inverted ? "white" : "transparent")};
- color: ${({ inverted }) => (inverted ? "black" : "white")};
+ background-color: ${({ inverted }) =>
+ inverted ? vscForeground : "transparent"};
+ color: ${({ inverted }) => (inverted ? vscBackground : vscForeground)};
border: none;
border-radius: ${defaultBorderRadius};
@@ -146,7 +151,9 @@ export const HeaderButton = styled.button<{ inverted: boolean | undefined }>`
&:hover {
background-color: ${({ inverted }) =>
- typeof inverted === "undefined" || inverted ? lightGray : "transparent"};
+ typeof inverted === "undefined" || inverted
+ ? secondaryDark
+ : "transparent"};
}
display: flex;
align-items: center;
diff --git a/extension/react-app/src/highlight/dark.min.css b/extension/react-app/src/highlight/dark.min.css
deleted file mode 100644
index 9268d7c9..00000000
--- a/extension/react-app/src/highlight/dark.min.css
+++ /dev/null
@@ -1,53 +0,0 @@
-pre code.hljs {
- display: block;
- overflow-x: auto;
- padding: 1em;
-}
-code.hljs {
- padding: 3px 5px;
-}
-.hljs {
- color: #ddd;
- background: #252526;
-}
-.hljs-keyword,
-.hljs-link,
-.hljs-literal,
-.hljs-section,
-.hljs-selector-tag {
- color: #fff;
-}
-.hljs-addition,
-.hljs-attribute,
-.hljs-built_in,
-.hljs-bullet,
-.hljs-name,
-.hljs-string,
-.hljs-symbol,
-.hljs-template-tag,
-.hljs-template-variable,
-.hljs-title,
-.hljs-type,
-.hljs-variable {
- color: #d88;
-}
-.hljs-comment,
-.hljs-deletion,
-.hljs-meta,
-.hljs-quote {
- color: #979797;
-}
-.hljs-doctag,
-.hljs-keyword,
-.hljs-literal,
-.hljs-name,
-.hljs-section,
-.hljs-selector-tag,
-.hljs-strong,
-.hljs-title,
-.hljs-type {
- font-weight: 700;
-}
-.hljs-emphasis {
- font-style: italic;
-}
diff --git a/extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts
new file mode 100644
index 00000000..6c0df8fc
--- /dev/null
+++ b/extension/react-app/src/hooks/AbstractContinueGUIClientProtocol.ts
@@ -0,0 +1,35 @@
+abstract class AbstractContinueGUIClientProtocol {
+ abstract sendMainInput(input: string): void;
+
+ abstract reverseToIndex(index: number): void;
+
+ abstract sendRefinementInput(input: string, index: number): void;
+
+ abstract sendStepUserInput(input: string, index: number): void;
+
+ abstract onStateUpdate(state: any): void;
+
+ abstract onAvailableSlashCommands(
+ callback: (commands: { name: string; description: string }[]) => void
+ ): void;
+
+ abstract changeDefaultModel(model: string): void;
+
+ abstract sendClear(): void;
+
+ abstract retryAtIndex(index: number): void;
+
+ abstract deleteAtIndex(index: number): void;
+
+ abstract deleteContextAtIndices(indices: number[]): void;
+
+ abstract setEditingAtIndices(indices: number[]): void;
+
+ abstract setPinnedAtIndices(indices: number[]): void;
+
+ abstract toggleAddingHighlightedCode(): void;
+
+ abstract showLogsAtIndex(index: number): void;
+}
+
+export default AbstractContinueGUIClientProtocol;
diff --git a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
index a179c2bf..7d6c2a71 100644
--- a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
+++ b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
@@ -1,33 +1,92 @@
-abstract class AbstractContinueGUIClientProtocol {
- abstract sendMainInput(input: string): void;
+import AbstractContinueGUIClientProtocol from "./AbstractContinueGUIClientProtocol";
+import { Messenger, WebsocketMessenger } from "./messenger";
+import { VscodeMessenger } from "./vscodeMessenger";
- abstract reverseToIndex(index: number): void;
+class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol {
+ messenger: Messenger;
+ // Server URL must contain the session ID param
+ serverUrlWithSessionId: string;
- abstract sendRefinementInput(input: string, index: number): void;
+ constructor(
+ serverUrlWithSessionId: string,
+ useVscodeMessagePassing: boolean
+ ) {
+ super();
+ this.serverUrlWithSessionId = serverUrlWithSessionId;
+ this.messenger = useVscodeMessagePassing
+ ? new VscodeMessenger(serverUrlWithSessionId)
+ : new WebsocketMessenger(serverUrlWithSessionId);
+ }
- abstract sendStepUserInput(input: string, index: number): void;
+ sendMainInput(input: string) {
+ this.messenger.send("main_input", { input });
+ }
- abstract onStateUpdate(state: any): void;
+ reverseToIndex(index: number) {
+ this.messenger.send("reverse_to_index", { index });
+ }
- abstract onAvailableSlashCommands(
+ sendRefinementInput(input: string, index: number) {
+ this.messenger.send("refinement_input", { input, index });
+ }
+
+ sendStepUserInput(input: string, index: number) {
+ this.messenger.send("step_user_input", { input, index });
+ }
+
+ onStateUpdate(callback: (state: any) => void) {
+ this.messenger.onMessageType("state_update", (data: any) => {
+ if (data.state) {
+ callback(data.state);
+ }
+ });
+ }
+
+ onAvailableSlashCommands(
callback: (commands: { name: string; description: string }[]) => void
- ): void;
+ ) {
+ this.messenger.onMessageType("available_slash_commands", (data: any) => {
+ if (data.commands) {
+ callback(data.commands);
+ }
+ });
+ }
+
+ changeDefaultModel(model: string) {
+ this.messenger.send("change_default_model", { model });
+ }
- abstract changeDefaultModel(model: string): void;
+ sendClear() {
+ this.messenger.send("clear_history", {});
+ }
- abstract sendClear(): void;
+ retryAtIndex(index: number) {
+ this.messenger.send("retry_at_index", { index });
+ }
- abstract retryAtIndex(index: number): void;
+ deleteAtIndex(index: number) {
+ this.messenger.send("delete_at_index", { index });
+ }
- abstract deleteAtIndex(index: number): void;
+ deleteContextAtIndices(indices: number[]) {
+ this.messenger.send("delete_context_at_indices", { indices });
+ }
- abstract deleteContextAtIndices(indices: number[]): void;
+ setEditingAtIndices(indices: number[]) {
+ this.messenger.send("set_editing_at_indices", { indices });
+ }
- abstract setEditingAtIndices(indices: number[]): void;
+ setPinnedAtIndices(indices: number[]) {
+ this.messenger.send("set_pinned_at_indices", { indices });
+ }
- abstract setPinnedAtIndices(indices: number[]): void;
+ toggleAddingHighlightedCode(): void {
+ this.messenger.send("toggle_adding_highlighted_code", {});
+ }
- abstract toggleAddingHighlightedCode(): void;
+ showLogsAtIndex(index: number): void {
+ this.messenger.send("show_logs_at_index", { index });
+ }
}
-export default AbstractContinueGUIClientProtocol;
+export default ContinueGUIClientProtocol;
diff --git a/extension/react-app/src/hooks/messenger.ts b/extension/react-app/src/hooks/messenger.ts
index e2a0bab8..00ce1fbb 100644
--- a/extension/react-app/src/hooks/messenger.ts
+++ b/extension/react-app/src/hooks/messenger.ts
@@ -1,6 +1,3 @@
-// console.log("Websocket import");
-// const WebSocket = require("ws");
-
export abstract class Messenger {
abstract send(messageType: string, data: object): void;
@@ -28,13 +25,6 @@ export class WebsocketMessenger extends Messenger {
private serverUrl: string;
_newWebsocket(): WebSocket {
- // // Dynamic import, because WebSocket is builtin with browser, but not with node. And can't use require in browser.
- // if (typeof process === "object") {
- // console.log("Using node");
- // // process is only available in Node
- // var WebSocket = require("ws");
- // }
-
const newWebsocket = new WebSocket(this.serverUrl);
for (const listener of this.onOpenListeners) {
this.onOpen(listener);
diff --git a/extension/react-app/src/hooks/useContinueGUIProtocol.ts b/extension/react-app/src/hooks/useContinueGUIProtocol.ts
deleted file mode 100644
index 2060dd7f..00000000
--- a/extension/react-app/src/hooks/useContinueGUIProtocol.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import AbstractContinueGUIClientProtocol from "./ContinueGUIClientProtocol";
-// import { Messenger, WebsocketMessenger } from "../../../src/util/messenger";
-import { Messenger, WebsocketMessenger } from "./messenger";
-import { VscodeMessenger } from "./vscodeMessenger";
-
-class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol {
- messenger: Messenger;
- // Server URL must contain the session ID param
- serverUrlWithSessionId: string;
-
- constructor(
- serverUrlWithSessionId: string,
- useVscodeMessagePassing: boolean
- ) {
- super();
- this.serverUrlWithSessionId = serverUrlWithSessionId;
- if (useVscodeMessagePassing) {
- this.messenger = new VscodeMessenger(serverUrlWithSessionId);
- } else {
- this.messenger = new WebsocketMessenger(serverUrlWithSessionId);
- }
- }
-
- sendMainInput(input: string) {
- this.messenger.send("main_input", { input });
- }
-
- reverseToIndex(index: number) {
- this.messenger.send("reverse_to_index", { index });
- }
-
- sendRefinementInput(input: string, index: number) {
- this.messenger.send("refinement_input", { input, index });
- }
-
- sendStepUserInput(input: string, index: number) {
- this.messenger.send("step_user_input", { input, index });
- }
-
- onStateUpdate(callback: (state: any) => void) {
- this.messenger.onMessageType("state_update", (data: any) => {
- if (data.state) {
- callback(data.state);
- }
- });
- }
-
- onAvailableSlashCommands(
- callback: (commands: { name: string; description: string }[]) => void
- ) {
- this.messenger.onMessageType("available_slash_commands", (data: any) => {
- if (data.commands) {
- callback(data.commands);
- }
- });
- }
-
- changeDefaultModel(model: string) {
- this.messenger.send("change_default_model", { model });
- }
-
- sendClear() {
- this.messenger.send("clear_history", {});
- }
-
- retryAtIndex(index: number) {
- this.messenger.send("retry_at_index", { index });
- }
-
- deleteAtIndex(index: number) {
- this.messenger.send("delete_at_index", { index });
- }
-
- deleteContextAtIndices(indices: number[]) {
- this.messenger.send("delete_context_at_indices", { indices });
- }
-
- setEditingAtIndices(indices: number[]) {
- this.messenger.send("set_editing_at_indices", { indices });
- }
-
- setPinnedAtIndices(indices: number[]) {
- this.messenger.send("set_pinned_at_indices", { indices });
- }
-
- toggleAddingHighlightedCode(): void {
- this.messenger.send("toggle_adding_highlighted_code", {});
- }
-}
-
-export default ContinueGUIClientProtocol;
diff --git a/extension/react-app/src/hooks/useWebsocket.ts b/extension/react-app/src/hooks/useWebsocket.ts
index e762666f..6b36be97 100644
--- a/extension/react-app/src/hooks/useWebsocket.ts
+++ b/extension/react-app/src/hooks/useWebsocket.ts
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import { RootStore } from "../redux/store";
import { useSelector } from "react-redux";
-import ContinueGUIClientProtocol from "./useContinueGUIProtocol";
+import ContinueGUIClientProtocol from "./ContinueGUIClientProtocol";
import { postVscMessage } from "../vscode";
function useContinueGUIProtocol(useVscodeMessagePassing: boolean = true) {
diff --git a/extension/react-app/src/index.css b/extension/react-app/src/index.css
index 6e33c89c..bac7fe97 100644
--- a/extension/react-app/src/index.css
+++ b/extension/react-app/src/index.css
@@ -14,13 +14,13 @@ html,
body,
#root {
height: 100%;
- background-color: var(--vsc-background);
+ background-color: var(--vscode-editor-background);
font-family: "Lexend", sans-serif;
}
body {
padding: 0;
- color: white;
+ color: var(--vscode-editor-foreground);
padding: 0px;
margin: 0px;
height: 100%;
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/pages/gui.tsx
index e1ecec9e..fccc9b4b 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/pages/gui.tsx
@@ -1,5 +1,9 @@
import styled from "styled-components";
-import { defaultBorderRadius } from "../components";
+import {
+ defaultBorderRadius,
+ vscBackground,
+ vscForeground,
+} from "../components";
import Loader from "../components/Loader";
import ContinueButton from "../components/ContinueButton";
import { FullState, HighlightedRangeContext } from "../../../schema/FullState";
@@ -20,9 +24,10 @@ import ReactSwitch from "react-switch";
import { usePostHog } from "posthog-js/react";
import { useSelector } from "react-redux";
import { RootStore } from "../redux/store";
-import LoadingCover from "../components/LoadingCover";
import { postVscMessage } from "../vscode";
import UserInputContainer from "../components/UserInputContainer";
+import Onboarding from "../components/Onboarding";
+import { isMetaEquivalentKeyPressed } from "../util";
const TopGUIDiv = styled.div`
overflow: hidden;
@@ -95,11 +100,8 @@ function GUI(props: GUIProps) {
name: "Welcome to Continue",
hide: false,
description: `- Highlight code and ask a question or give instructions
-- Use \`cmd+k\` (Mac) / \`ctrl+k\` (Windows) to open Continue
-- Use \`cmd+shift+e\` / \`ctrl+shift+e\` to open file Explorer
-- Add your own OpenAI API key to VS Code Settings with \`cmd+,\`
-- Use slash commands when you want fine-grained control
-- Past steps are included as part of the context by default`,
+ - Use \`cmd+m\` (Mac) / \`ctrl+m\` (Windows) to open Continue
+ - Use \`/help\` to ask questions about how to use Continue`,
system_message: null,
chat_context: [],
manage_own_chat_context: false,
@@ -140,13 +142,14 @@ function GUI(props: GUIProps) {
useEffect(() => {
const listener = (e: any) => {
// Cmd + i to toggle fast model
- if (e.key === "i" && e.metaKey && e.shiftKey) {
+ if (e.key === "i" && isMetaEquivalentKeyPressed(e) && e.shiftKey) {
setUsingFastModel((prev) => !prev);
// Cmd + backspace to stop currently running step
} else if (
e.key === "Backspace" &&
- e.metaKey &&
- typeof history?.current_index !== "undefined"
+ isMetaEquivalentKeyPressed(e) &&
+ typeof history?.current_index !== "undefined" &&
+ history.timeline[history.current_index]?.active
) {
client?.deleteAtIndex(history.current_index);
}
@@ -169,6 +172,7 @@ function GUI(props: GUIProps) {
const waitingForSteps =
state.active &&
state.history.current_index < state.history.timeline.length &&
+ state.history.timeline[state.history.current_index] &&
state.history.timeline[
state.history.current_index
].step.description?.trim() === "";
@@ -221,7 +225,7 @@ function GUI(props: GUIProps) {
if (mainTextInputRef.current) {
let input = (mainTextInputRef.current as any).inputValue;
// cmd+enter to /edit
- if (event?.metaKey) {
+ if (isMetaEquivalentKeyPressed(event)) {
input = `/edit ${input}`;
}
(mainTextInputRef.current as any).setInputValue("");
@@ -235,14 +239,14 @@ function GUI(props: GUIProps) {
history.current_index < history.timeline.length
) {
if (
- history.timeline[history.current_index].step.name ===
+ history.timeline[history.current_index]?.step.name ===
"Waiting for user input"
) {
if (input.trim() === "") return;
onStepUserInput(input, history!.current_index);
return;
} else if (
- history.timeline[history.current_index].step.name ===
+ history.timeline[history.current_index]?.step.name ===
"Waiting for user confirmation"
) {
onStepUserInput("ok", history!.current_index);
@@ -260,14 +264,13 @@ function GUI(props: GUIProps) {
const onStepUserInput = (input: string, index: number) => {
if (!client) return;
- console.log("Sending step user input", input, index);
client.sendStepUserInput(input, index);
};
// const iterations = useSelector(selectIterations);
return (
<>
- <LoadingCover hidden={true} message="Downloading local model..." />
+ <Onboarding />
<TextDialog
showDialog={showFeedbackDialog}
onEnter={(text) => {
@@ -278,7 +281,7 @@ function GUI(props: GUIProps) {
setShowFeedbackDialog(false);
}}
message={feedbackDialogMessage}
- ></TextDialog>
+ />
<TopGUIDiv
ref={topGuiDivRef}
@@ -308,6 +311,7 @@ function GUI(props: GUIProps) {
)
) : (
<StepContainer
+ index={index}
isLast={index === history.timeline.length - 1}
isFirst={index === 0}
open={stepsOpen[index]}
@@ -348,12 +352,6 @@ function GUI(props: GUIProps) {
</div>
<ComboBox
- // disabled={
- // history?.timeline.length
- // ? history.timeline[history.current_index].step.name ===
- // "Waiting for user confirmation"
- // : false
- // }
ref={mainTextInputRef}
onEnter={(e) => {
onMainTextInput(e);
@@ -378,12 +376,13 @@ function GUI(props: GUIProps) {
style={{
position: "fixed",
bottom: "50px",
- backgroundColor: "white",
- color: "black",
+ backgroundColor: vscBackground,
+ color: vscForeground,
borderRadius: defaultBorderRadius,
padding: "16px",
margin: "16px",
zIndex: 100,
+ boxShadow: `0px 0px 10px 0px ${vscForeground}`,
}}
hidden={!showDataSharingInfo}
>
@@ -438,7 +437,7 @@ function GUI(props: GUIProps) {
if (!usingFastModel) {
// Show the dialog
setFeedbackDialogMessage(
- "We don't yet support local models, but we're working on it! If privacy is a concern of yours, please use the feedback button in the bottom right to let us know."
+ "We don't yet support local models, but we're working on it! If privacy is a concern of yours, please write a short note to let us know."
);
setShowFeedbackDialog(true);
}
diff --git a/extension/react-app/src/tabs/additionalContext.tsx b/extension/react-app/src/tabs/additionalContext.tsx
deleted file mode 100644
index 98fce9f1..00000000
--- a/extension/react-app/src/tabs/additionalContext.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from "react";
-import { H3, TextArea } from "../components";
-
-function AdditionalContextTab() {
- return (
- <div className="mx-5">
- <H3>Additional Context</H3>
- <TextArea
- rows={8}
- placeholder="Copy and paste information related to the bug from GitHub Issues, Slack threads, or other notes here."
- className="additionalContextTextarea"
- ></TextArea>
- <br></br>
- </div>
- );
-}
-
-export default AdditionalContextTab;
diff --git a/extension/react-app/src/tabs/chat/MessageDiv.tsx b/extension/react-app/src/tabs/chat/MessageDiv.tsx
deleted file mode 100644
index 3543dd93..00000000
--- a/extension/react-app/src/tabs/chat/MessageDiv.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import React, { useEffect } from "react";
-import { ChatMessage } from "../../redux/store";
-import styled from "styled-components";
-import {
- buttonColor,
- defaultBorderRadius,
- secondaryDark,
-} from "../../components";
-import VSCodeFileLink from "../../components/VSCodeFileLink";
-import ReactMarkdown from "react-markdown";
-import "../../highlight/dark.min.css";
-import hljs from "highlight.js";
-import { useSelector } from "react-redux";
-import { selectIsStreaming } from "../../redux/selectors/chatSelectors";
-
-const Container = styled.div`
- padding-left: 8px;
- padding-right: 8px;
- border-radius: 8px;
- margin: 3px;
- width: fit-content;
- max-width: 75%;
- overflow-y: scroll;
- word-wrap: break-word;
- -ms-word-wrap: break-word;
- height: fit-content;
- overflow: hidden;
- background-color: ${(props) => {
- if (props.role === "user") {
- return buttonColor;
- } else {
- return secondaryDark;
- }
- }};
- float: ${(props) => {
- if (props.role === "user") {
- return "right";
- } else {
- return "left";
- }
- }};
- display: block;
-
- & pre {
- border: 1px solid gray;
- border-radius: ${defaultBorderRadius};
- }
-`;
-
-function MessageDiv(props: ChatMessage) {
- const [richContent, setRichContent] = React.useState<JSX.Element[]>([]);
- const isStreaming = useSelector(selectIsStreaming);
-
- useEffect(() => {
- if (!isStreaming) {
- hljs.highlightAll();
- }
- }, [richContent, isStreaming]);
-
- useEffect(() => {
- setRichContent([
- <ReactMarkdown key={1} children={props.content}></ReactMarkdown>,
- ]);
- }, [props.content]);
-
- return (
- <>
- <div className="overflow-auto">
- <Container role={props.role}>{richContent}</Container>
- </div>
- </>
- );
-}
-
-export default MessageDiv;
diff --git a/extension/react-app/src/tabs/chat/index.tsx b/extension/react-app/src/tabs/chat/index.tsx
deleted file mode 100644
index a93ad4f9..00000000
--- a/extension/react-app/src/tabs/chat/index.tsx
+++ /dev/null
@@ -1,267 +0,0 @@
-import React, { useCallback, useEffect, useRef, useState } from "react";
-import { useDispatch, useSelector } from "react-redux";
-import { selectChatMessages } from "../../redux/selectors/chatSelectors";
-import MessageDiv from "./MessageDiv";
-import styled from "styled-components";
-import { addMessage, setIsStreaming } from "../../redux/slices/chatSlice";
-import { AnyAction, Dispatch } from "@reduxjs/toolkit";
-import { closeStream, streamUpdate } from "../../redux/slices/chatSlice";
-import { ChatMessage, RootStore } from "../../redux/store";
-import { postVscMessage, vscRequest } from "../../vscode";
-import { defaultBorderRadius, Loader } from "../../components";
-import { selectHighlightedCode } from "../../redux/selectors/miscSelectors";
-import { readRangeInVirtualFileSystem } from "../../util";
-import { selectDebugContext } from "../../redux/selectors/debugContextSelectors";
-
-let textEntryBarHeight = "30px";
-
-const ChatContainer = styled.div`
- display: grid;
- grid-template-rows: 1fr auto;
- height: 100%;
-`;
-
-const BottomDiv = styled.div`
- display: grid;
- grid-template-rows: auto auto;
-`;
-
-const BottomButton = styled.button(
- (props: { active: boolean }) => `
- font-size: 10px;
- border: none;
- color: white;
- margin-right: 4px;
- cursor: pointer;
- background-color: ${props.active ? "black" : "gray"};
- border-radius: ${defaultBorderRadius};
- padding: 8px;
-`
-);
-
-const TextEntryBar = styled.input`
- height: ${textEntryBarHeight};
- border-bottom-left-radius: ${defaultBorderRadius};
- border-bottom-right-radius: ${defaultBorderRadius};
- padding: 8px;
- border: 1px solid white;
- background-color: black;
- color: white;
- outline: none;
-`;
-
-function ChatTab() {
- const dispatch = useDispatch();
- const chatMessages = useSelector(selectChatMessages);
- const isStreaming = useSelector((state: RootStore) => state.chat.isStreaming);
- const baseUrl = useSelector((state: RootStore) => state.config.apiUrl);
- const debugContext = useSelector(selectDebugContext);
-
- const [includeHighlightedCode, setIncludeHighlightedCode] = useState(true);
- const [writeToEditor, setWriteToEditor] = useState(false);
- const [waitingForResponse, setWaitingForResponse] = useState(false);
-
- const highlightedCode = useSelector(selectHighlightedCode);
-
- const streamToStateThunk = useCallback(
- (dispatch: Dispatch<AnyAction>, getResponse: () => Promise<Response>) => {
- let streamToCursor = writeToEditor;
- getResponse().then((resp) => {
- setWaitingForResponse(false);
- if (resp.body) {
- resp.body.pipeTo(
- new WritableStream({
- write(chunk) {
- let update = new TextDecoder("utf-8").decode(chunk);
- dispatch(streamUpdate(update));
- if (streamToCursor) {
- postVscMessage("streamUpdate", { update });
- }
- },
- close() {
- dispatch(closeStream());
- if (streamToCursor) {
- postVscMessage("closeStream", null);
- }
- },
- })
- );
- }
- });
- },
- [writeToEditor]
- );
-
- const compileHiddenChatMessages = useCallback(async () => {
- let messages: ChatMessage[] = [];
- if (
- includeHighlightedCode &&
- highlightedCode?.filepath !== undefined &&
- highlightedCode?.range !== undefined &&
- debugContext.filesystem[highlightedCode.filepath] !== undefined
- ) {
- let fileContents = readRangeInVirtualFileSystem(
- highlightedCode,
- debugContext.filesystem
- );
- if (fileContents) {
- messages.push({
- role: "user",
- content: fileContents,
- });
- }
- } else {
- // Similarity search over workspace
- let data = await vscRequest("queryEmbeddings", {
- query: chatMessages[chatMessages.length - 1].content,
- });
- let codeContextMessages = data.results.map(
- (result: { id: string; document: string }) => {
- let msg: ChatMessage = {
- role: "user",
- content: `File: ${result.id} \n ${result.document}`,
- };
- return msg;
- }
- );
- codeContextMessages.push({
- role: "user",
- content:
- "Use the above code to help you answer the question below. Answer in asterisk bullet points, and give the full path whenever you reference files.",
- });
- messages.push(...codeContextMessages);
- }
-
- let systemMsgContent = writeToEditor
- ? "Respond only with the exact code requested, no additional text."
- : "Use the above code to help you answer the question below. Respond in markdown if using bullets or other special formatting, being sure to specify language for code blocks.";
-
- messages.push({
- role: "system",
- content: systemMsgContent,
- });
- return messages;
- }, [highlightedCode, chatMessages, includeHighlightedCode, writeToEditor]);
-
- useEffect(() => {
- if (
- chatMessages.length > 0 &&
- chatMessages[chatMessages.length - 1].role === "user" &&
- !isStreaming
- ) {
- dispatch(setIsStreaming(true));
- streamToStateThunk(dispatch, async () => {
- if (chatMessages.length === 0) {
- return new Promise((resolve, _) => resolve(new Response()));
- }
- let hiddenChatMessages = await compileHiddenChatMessages();
- let augmentedMessages = [
- ...chatMessages.slice(0, -1),
- ...hiddenChatMessages,
- chatMessages[chatMessages.length - 1],
- ];
- console.log(augmentedMessages);
- // The autogenerated client can't handle streams, so have to go raw
- return fetch(`${baseUrl}/chat/complete`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({
- messages: augmentedMessages,
- }),
- });
- });
- }
- }, [chatMessages, dispatch, isStreaming, highlightedCode]);
-
- const chatMessagesDiv = useRef<HTMLDivElement>(null);
- useEffect(() => {
- // Scroll to bottom
- let interval = setInterval(() => {
- if (chatMessagesDiv.current && !waitingForResponse) {
- chatMessagesDiv.current.scrollTop += Math.max(
- 4,
- 0.05 * chatMessagesDiv.current.scrollHeight -
- chatMessagesDiv.current.clientHeight -
- chatMessagesDiv.current.scrollTop
- );
- if (
- chatMessagesDiv.current.scrollTop >=
- chatMessagesDiv.current.scrollHeight -
- chatMessagesDiv.current.clientHeight
- ) {
- clearInterval(interval);
- }
- }
- }, 10);
- }, [chatMessages, chatMessagesDiv, waitingForResponse]);
-
- return (
- <ChatContainer>
- <div className="mx-5 overflow-y-scroll" ref={chatMessagesDiv}>
- <h1>Chat</h1>
- <hr></hr>
- <div>
- {chatMessages.length > 0 ? (
- chatMessages.map((message, idx) => {
- return <MessageDiv key={idx} {...message}></MessageDiv>;
- })
- ) : (
- <p className="text-gray-400 m-auto text-center">
- You can ask questions about your codebase or ask for code written
- directly in the editor.
- </p>
- )}
- {waitingForResponse && <Loader></Loader>}
- </div>
- </div>
-
- <BottomDiv>
- <div className="h-12 bg-secondary-">
- <div className="flex items-center p-2">
- {/* <p className="mr-auto text-xs">
- Highlighted code is automatically included in your chat message.
- </p> */}
- <BottomButton
- className="ml-auto"
- active={writeToEditor}
- onClick={() => {
- setWriteToEditor(!writeToEditor);
- }}
- >
- {writeToEditor ? "Writing to editor" : "Write to editor"}
- </BottomButton>
-
- <BottomButton
- active={includeHighlightedCode}
- onClick={() => {
- setIncludeHighlightedCode(!includeHighlightedCode);
- }}
- >
- {includeHighlightedCode
- ? "Including highlighted code"
- : "Automatically finding relevant code"}
- </BottomButton>
- </div>
- </div>
- <TextEntryBar
- type="text"
- placeholder="Enter your message here"
- onKeyDown={(e) => {
- if (e.key === "Enter" && e.currentTarget.value !== "") {
- console.log("Sending message", e.currentTarget.value);
- dispatch(
- addMessage({ content: e.currentTarget.value, role: "user" })
- );
- (e.target as any).value = "";
- setWaitingForResponse(true);
- }
- }}
- ></TextEntryBar>
- </BottomDiv>
- </ChatContainer>
- );
-}
-
-export default ChatTab;
diff --git a/extension/react-app/src/tabs/main.tsx b/extension/react-app/src/tabs/main.tsx
deleted file mode 100644
index a8b3300d..00000000
--- a/extension/react-app/src/tabs/main.tsx
+++ /dev/null
@@ -1,189 +0,0 @@
-import React, { useEffect, useState } from "react";
-import { H3, TextArea, Button, Pre, Loader } from "../components";
-import styled from "styled-components";
-import { postVscMessage, withProgress } from "../vscode";
-import { useDebugContextValue } from "../redux/hooks";
-import CodeMultiselect from "../components/CodeMultiselect";
-import { useSelector } from "react-redux";
-import { selectDebugContext } from "../redux/selectors/debugContextSelectors";
-import { useDispatch } from "react-redux";
-import { updateValue } from "../redux/slices/debugContexSlice";
-import { setWorkspacePath } from "../redux/slices/configSlice";
-import { SerializedDebugContext } from "../../../src/client";
-import { useEditCache } from "../util/editCache";
-import { useApi } from "../util/api";
-
-const ButtonDiv = styled.div`
- display: flex;
- justify-content: space-between;
- align-items: center;
- gap: 4px;
- margin: 4px;
- flex-wrap: wrap;
-
- & button {
- flex-grow: 1;
- }
-`;
-
-function MainTab(props: any) {
- const dispatch = useDispatch();
-
- const [suggestion, setSuggestion] = useState("");
- const [traceback, setTraceback] = useDebugContextValue("traceback", "");
- const [selectedRanges, setSelectedRanges] = useDebugContextValue(
- "rangesInFiles",
- []
- );
-
- const editCache = useEditCache();
- const { debugApi } = useApi();
-
- const [responseLoading, setResponseLoading] = useState(false);
-
- let debugContext = useSelector(selectDebugContext);
-
- useEffect(() => {
- editCache.preloadEdit(debugContext);
- }, [debugContext]);
-
- function postVscMessageWithDebugContext(
- type: string,
- overrideDebugContext: SerializedDebugContext | null = null
- ) {
- postVscMessage(type, {
- debugContext: overrideDebugContext || debugContext,
- });
- }
-
- function launchFindSuspiciousCode(newTraceback: string) {
- // setTraceback's effects don't occur immediately, so we have to add it to the debug context manually
- let updatedDebugContext = {
- ...debugContext,
- traceback: newTraceback,
- };
- postVscMessageWithDebugContext("findSuspiciousCode", updatedDebugContext);
- postVscMessageWithDebugContext("preloadEdit", updatedDebugContext);
- }
-
- useEffect(() => {
- const eventListener = (event: any) => {
- switch (event.data.type) {
- case "suggestFix":
- case "explainCode":
- case "listTenThings":
- setSuggestion(event.data.value);
- setResponseLoading(false);
- break;
- case "traceback":
- setTraceback(event.data.value);
- launchFindSuspiciousCode(event.data.value);
- break;
- case "workspacePath":
- dispatch(setWorkspacePath(event.data.value));
- break;
- }
- };
- window.addEventListener("message", eventListener);
-
- return () => window.removeEventListener("message", eventListener);
- }, [debugContext, selectedRanges]);
-
- return (
- <div className="mx-5">
- <h1>Debug Panel</h1>
-
- <H3>Code Sections</H3>
- <CodeMultiselect></CodeMultiselect>
-
- <H3>Bug Description</H3>
- <TextArea
- id="bugDescription"
- name="bugDescription"
- className="bugDescription"
- rows={4}
- cols={50}
- placeholder="Describe your bug..."
- ></TextArea>
-
- <H3>Stack Trace</H3>
- <TextArea
- id="traceback"
- className="traceback"
- name="traceback"
- rows={4}
- cols={50}
- placeholder="Paste stack trace here"
- onChange={(e) => {
- setTraceback(e.target.value);
- dispatch(updateValue({ key: "traceback", value: e.target.value }));
- // postVscMessageWithDebugContext("findSuspiciousCode");
- }}
- onPaste={(e) => {
- let pasted = e.clipboardData.getData("text");
- console.log("PASTED", pasted);
- setTraceback(pasted);
- launchFindSuspiciousCode(pasted);
- }}
- value={traceback}
- ></TextArea>
-
- <select
- hidden
- id="relevantVars"
- className="relevantVars"
- name="relevantVars"
- ></select>
-
- <ButtonDiv>
- <Button
- onClick={() => {
- postVscMessageWithDebugContext("explainCode");
- setResponseLoading(true);
- }}
- >
- Explain Code
- </Button>
- <Button
- onClick={() => {
- postVscMessageWithDebugContext("suggestFix");
- setResponseLoading(true);
- }}
- >
- Generate Ideas
- </Button>
- <Button
- disabled={selectedRanges.length === 0}
- onClick={async () => {
- withProgress("Generating Fix", async () => {
- let edits = await editCache.getEdit(debugContext);
- postVscMessage("makeEdit", { edits });
- });
- }}
- >
- Suggest Fix
- </Button>
- <Button
- disabled={selectedRanges.length === 0}
- onClick={() => {
- postVscMessageWithDebugContext("generateUnitTest");
- }}
- >
- Create Test
- </Button>
- </ButtonDiv>
- <Loader hidden={!responseLoading}></Loader>
-
- <Pre
- className="fixSuggestion"
- hidden={!(typeof suggestion === "string" && suggestion.length > 0)}
- >
- {suggestion}
- </Pre>
-
- <br></br>
- </div>
- );
-}
-
-export default MainTab;
diff --git a/extension/react-app/src/tabs/welcome.tsx b/extension/react-app/src/tabs/welcome.tsx
deleted file mode 100644
index c29d260a..00000000
--- a/extension/react-app/src/tabs/welcome.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import React from "react";
-
-function WelcomeTab() {
- return (
- <div className="mx-5">
- <h1>Welcome to Continue</h1>
-
- <p>
- Learn more in the{" "}
- <a href="https://www.notion.so/continue-dev/Continue-User-Guide-1c6ad99887d0474d9e42206f6c98efa4">
- Continue User Guide
- </a>{" "}
- </p>
- <p>Send Nate or Ty your feedback:</p>
- <p>1. What excites you about Continue?</p>
- <p>2. What did you struggle with when using Continue?</p>
- <p>3. How do you wish Continue worked?</p>
- </div>
- );
-}
-
-export default WelcomeTab;
diff --git a/extension/react-app/src/util/api.ts b/extension/react-app/src/util/api.ts
deleted file mode 100644
index bdec1d20..00000000
--- a/extension/react-app/src/util/api.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-import {
- Configuration,
- DebugApi,
- UnittestApi,
- ChatApi,
-} from "../../../src/client";
-import { useSelector } from "react-redux";
-import { useEffect, useState } from "react";
-import { RootStore } from "../redux/store";
-
-export function useApi() {
- const apiUrl = useSelector((state: RootStore) => state.config.apiUrl);
- const vscMachineId = useSelector(
- (state: RootStore) => state.config.vscMachineId
- );
- const [debugApi, setDebugApi] = useState<DebugApi>();
- const [unittestApi, setUnittestApi] = useState<UnittestApi>();
- const [chatApi, setChatApi] = useState<ChatApi>();
-
- useEffect(() => {
- if (apiUrl && vscMachineId) {
- let config = new Configuration({
- basePath: apiUrl,
- fetchApi: fetch,
- middleware: [
- {
- pre: async (context) => {
- context.init.headers = {
- ...context.init.headers,
- "x-vsc-machine-id": vscMachineId,
- };
- },
- },
- ],
- });
- setDebugApi(new DebugApi(config));
- setUnittestApi(new UnittestApi(config));
- setChatApi(new ChatApi(config));
- }
- }, [apiUrl, vscMachineId]);
-
- return { debugApi, unittestApi, chatApi };
-}
diff --git a/extension/react-app/src/util/editCache.ts b/extension/react-app/src/util/editCache.ts
deleted file mode 100644
index b8071127..00000000
--- a/extension/react-app/src/util/editCache.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { useApi } from "../util/api";
-import { FileEdit, SerializedDebugContext } from "../../../src/client";
-import { useCallback, useEffect, useState } from "react";
-
-export function useEditCache() {
- const { debugApi } = useApi();
-
- const fetchNewEdit = useCallback(
- async (debugContext: SerializedDebugContext) => {
- return (
- await debugApi?.editEndpointDebugEditPost({
- serializedDebugContext: debugContext,
- })
- )?.completion;
- },
- [debugApi]
- );
-
- const [editCache, setEditCache] = useState(new EditCache(fetchNewEdit));
-
- useEffect(() => {
- setEditCache(new EditCache(fetchNewEdit));
- }, [fetchNewEdit]);
-
- return editCache;
-}
-
-/**
- * Stores preloaded edits, invalidating based off of debug context changes
- */
-class EditCache {
- private _lastDebugContext: SerializedDebugContext | undefined;
- private _cachedEdits: FileEdit[] | undefined;
- private _fetchNewEdit: (
- debugContext: SerializedDebugContext
- ) => Promise<FileEdit[] | undefined>;
- private _debounceTimer: NodeJS.Timeout | undefined;
-
- private _debugContextChanged(debugContext: SerializedDebugContext): boolean {
- if (!this._lastDebugContext) {
- return true;
- }
-
- return (
- JSON.stringify(this._lastDebugContext) !== JSON.stringify(debugContext)
- );
- }
-
- private _debugContextComplete(debugContext: SerializedDebugContext): boolean {
- return debugContext.rangesInFiles.length > 0;
- }
-
- public async preloadEdit(debugContext: SerializedDebugContext) {
- if (this._debounceTimer) {
- clearTimeout(this._debounceTimer);
- }
- if (
- this._debugContextComplete(debugContext) &&
- this._debugContextChanged(debugContext)
- ) {
- this._debounceTimer = setTimeout(async () => {
- console.log("Preloading edits");
- this._cachedEdits = await this._fetchNewEdit(debugContext);
- this._lastDebugContext = debugContext;
- }, 200);
- }
- }
-
- public async getEdit(
- debugContext: SerializedDebugContext
- ): Promise<FileEdit[]> {
- if (this._debugContextChanged(debugContext)) {
- console.log("Cache miss");
- this._cachedEdits = await this._fetchNewEdit(debugContext);
- } else {
- console.log("Cache hit");
- }
-
- return this._cachedEdits!;
- }
-
- constructor(
- fetchNewEdit: (
- debugContext: SerializedDebugContext
- ) => Promise<FileEdit[] | undefined>
- ) {
- this._fetchNewEdit = fetchNewEdit;
- }
-}
diff --git a/extension/react-app/src/util/index.ts b/extension/react-app/src/util/index.ts
index 458f9d95..c4168e13 100644
--- a/extension/react-app/src/util/index.ts
+++ b/extension/react-app/src/util/index.ts
@@ -1,27 +1,43 @@
-import { RangeInFile } from "../../../src/client";
+type Platform = "mac" | "linux" | "windows" | "unknown";
-export function readRangeInVirtualFileSystem(
- rangeInFile: RangeInFile,
- filesystem: { [filepath: string]: string }
-): string | undefined {
- const range = rangeInFile.range;
-
- let data = filesystem[rangeInFile.filepath];
- if (data === undefined) {
- console.log("File not found");
- return undefined;
+export function getPlatform(): Platform {
+ const platform = window.navigator.platform.toUpperCase();
+ if (platform.indexOf("MAC") >= 0) {
+ return "mac";
+ } else if (platform.indexOf("LINUX") >= 0) {
+ return "linux";
+ } else if (platform.indexOf("WIN") >= 0) {
+ return "windows";
} else {
- let lines = data.toString().split("\n");
- if (range.start.line === range.end.line) {
- return lines[rangeInFile.range.start.line].slice(
- rangeInFile.range.start.character,
- rangeInFile.range.end.character
- );
- } else {
- let firstLine = lines[range.start.line].slice(range.start.character);
- let lastLine = lines[range.end.line].slice(0, range.end.character);
- let middleLines = lines.slice(range.start.line + 1, range.end.line);
- return [firstLine, ...middleLines, lastLine].join("\n");
- }
+ return "unknown";
+ }
+}
+
+export function isMetaEquivalentKeyPressed(event: {
+ metaKey: boolean;
+ ctrlKey: boolean;
+}): boolean {
+ const platform = getPlatform();
+ switch (platform) {
+ case "mac":
+ return event.metaKey;
+ case "linux":
+ case "windows":
+ return event.ctrlKey;
+ default:
+ return event.metaKey;
+ }
+}
+
+export function getMetaKeyLabel(): string {
+ const platform = getPlatform();
+ switch (platform) {
+ case "mac":
+ return "⌘";
+ case "linux":
+ case "windows":
+ return "^";
+ default:
+ return "⌘";
}
}