summaryrefslogtreecommitdiff
path: root/extension
diff options
context:
space:
mode:
Diffstat (limited to 'extension')
-rw-r--r--extension/package-lock.json4
-rw-r--r--extension/package.json2
-rw-r--r--extension/react-app/package-lock.json402
-rw-r--r--extension/react-app/package.json3
-rw-r--r--extension/react-app/public/continue.gifbin0 -> 5242 bytes
-rw-r--r--extension/react-app/src/components/CodeBlock.tsx83
-rw-r--r--extension/react-app/src/components/ContinueButton.tsx13
-rw-r--r--extension/react-app/src/components/DebugPanel.tsx2
-rw-r--r--extension/react-app/src/components/HeaderButtonWithText.tsx8
-rw-r--r--extension/react-app/src/components/LoadingCover.tsx50
-rw-r--r--extension/react-app/src/components/StepContainer.tsx1
-rw-r--r--extension/react-app/src/components/StyledCode.tsx19
-rw-r--r--extension/react-app/src/components/TextDialog.tsx2
-rw-r--r--extension/react-app/src/hooks/ContinueGUIClientProtocol.ts2
-rw-r--r--extension/react-app/src/hooks/useContinueGUIProtocol.ts4
-rw-r--r--extension/react-app/src/redux/slices/configSlice.ts16
-rw-r--r--extension/react-app/src/redux/store.ts1
-rw-r--r--extension/react-app/src/tabs/gui.tsx44
-rw-r--r--extension/schema/History.d.ts29
-rw-r--r--extension/schema/HistoryNode.d.ts29
-rw-r--r--extension/scripts/.gitignore4
-rw-r--r--extension/scripts/continuedev-0.1.1-py3-none-any.whlbin86409 -> 0 bytes
-rw-r--r--extension/src/activation/activate.ts52
-rw-r--r--extension/src/activation/environmentSetup.ts185
-rw-r--r--extension/src/commands.ts94
-rw-r--r--extension/src/continueIdeClient.ts16
-rw-r--r--extension/src/debugPanel.ts174
-rw-r--r--extension/src/decorations.ts97
-rw-r--r--extension/src/extension.ts3
-rw-r--r--extension/src/lang-server/codeLens.ts32
-rw-r--r--extension/src/languages/index.d.ts13
-rw-r--r--extension/src/languages/index.ts19
-rw-r--r--extension/src/languages/javascript/index.ts16
-rw-r--r--extension/src/languages/notImplemented.ts10
-rw-r--r--extension/src/languages/python/index.ts74
35 files changed, 804 insertions, 699 deletions
diff --git a/extension/package-lock.json b/extension/package-lock.json
index 79b010cc..88cad6c6 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.60",
+ "version": "0.0.73",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.60",
+ "version": "0.0.73",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index 63a49173..ceba8698 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "Accelerating software development with language models",
- "version": "0.0.60",
+ "version": "0.0.73",
"publisher": "Continue",
"engines": {
"vscode": "^1.74.0"
diff --git a/extension/react-app/package-lock.json b/extension/react-app/package-lock.json
index db15fd2b..85b8633b 100644
--- a/extension/react-app/package-lock.json
+++ b/extension/react-app/package-lock.json
@@ -12,17 +12,20 @@
"@types/vscode-webview": "^1.57.1",
"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",
"styled-components": "^5.3.6",
"vscode-webview": "^1.0.1-beta.1"
},
"devDependencies": {
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
+ "@types/react-syntax-highlighter": "^15.5.7",
"@types/styled-components": "^5.1.26",
"@vitejs/plugin-react-swc": "^3.0.0",
"autoprefixer": "^10.4.13",
@@ -952,6 +955,15 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-syntax-highlighter": {
+ "version": "15.5.7",
+ "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.7.tgz",
+ "integrity": "sha512-bo5fEO5toQeyCp0zVHBeggclqf5SQ/Z5blfFmjwO5dkMVGPgmiwZsJh9nu/Bo5L7IHTuGWrja6LxJVE2uB5ZrQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@@ -1223,6 +1235,24 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -1534,6 +1564,18 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fault": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+ "dependencies": {
+ "format": "^0.2.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/fflate": {
"version": "0.4.8",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
@@ -1551,6 +1593,14 @@
"node": ">=8"
}
},
+ "node_modules/format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
"node_modules/fraction.js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -1642,6 +1692,15 @@
"node": ">=4"
}
},
+ "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",
+ "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
+ "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",
@@ -1651,6 +1710,60 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/hastscript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
+ "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^1.0.0",
+ "hast-util-parse-selector": "^2.0.0",
+ "property-information": "^5.0.0",
+ "space-separated-tokens": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hastscript/node_modules/comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/hastscript/node_modules/property-information": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/hastscript/node_modules/space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -1669,6 +1782,28 @@
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
"integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q=="
},
+ "node_modules/is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "dependencies": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -1715,6 +1850,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -1736,6 +1880,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -1816,6 +1969,19 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lowlight": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
+ "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
+ "dependencies": {
+ "fault": "^1.0.0",
+ "highlight.js": "~10.7.0"
+ },
+ "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",
@@ -2403,6 +2569,32 @@
"node": ">= 6"
}
},
+ "node_modules/parse-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+ "dependencies": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/parse-entities/node_modules/character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -2570,6 +2762,14 @@
"rrweb-snapshot": "^1.1.14"
}
},
+ "node_modules/prismjs": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -2734,6 +2934,21 @@
"react-dom": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
+ "node_modules/react-syntax-highlighter": {
+ "version": "15.5.0",
+ "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
+ "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "highlight.js": "^10.4.1",
+ "lowlight": "^1.17.0",
+ "prismjs": "^1.27.0",
+ "refractor": "^3.6.0"
+ },
+ "peerDependencies": {
+ "react": ">= 0.14.0"
+ }
+ },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -2755,6 +2970,28 @@
"node": ">=8.10.0"
}
},
+ "node_modules/refractor": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
+ "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
+ "dependencies": {
+ "hastscript": "^6.0.0",
+ "parse-entities": "^2.0.0",
+ "prismjs": "~1.27.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/refractor/node_modules/prismjs": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
+ "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
@@ -3304,7 +3541,6 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true,
"engines": {
"node": ">=0.4"
}
@@ -3859,6 +4095,15 @@
"@types/react": "*"
}
},
+ "@types/react-syntax-highlighter": {
+ "version": "15.5.7",
+ "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.7.tgz",
+ "integrity": "sha512-bo5fEO5toQeyCp0zVHBeggclqf5SQ/Z5blfFmjwO5dkMVGPgmiwZsJh9nu/Bo5L7IHTuGWrja6LxJVE2uB5ZrQ==",
+ "dev": true,
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
@@ -4041,6 +4286,16 @@
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
"integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="
},
+ "character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA=="
+ },
+ "character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
+ },
"chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -4284,6 +4539,14 @@
"reusify": "^1.0.4"
}
},
+ "fault": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+ "requires": {
+ "format": "^0.2.0"
+ }
+ },
"fflate": {
"version": "0.4.8",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
@@ -4298,6 +4561,11 @@
"to-regex-range": "^5.0.1"
}
},
+ "format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww=="
+ },
"fraction.js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -4360,11 +4628,53 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
},
+ "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-whitespace": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz",
"integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng=="
},
+ "hastscript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
+ "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
+ "requires": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^1.0.0",
+ "hast-util-parse-selector": "^2.0.0",
+ "property-information": "^5.0.0",
+ "space-separated-tokens": "^1.0.0"
+ },
+ "dependencies": {
+ "comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw=="
+ },
+ "property-information": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+ "requires": {
+ "xtend": "^4.0.0"
+ }
+ },
+ "space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA=="
+ }
+ }
+ },
+ "highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
+ },
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@@ -4385,6 +4695,20 @@
"resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz",
"integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q=="
},
+ "is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg=="
+ },
+ "is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "requires": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ }
+ },
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -4408,6 +4732,11 @@
"has": "^1.0.3"
}
},
+ "is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw=="
+ },
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -4423,6 +4752,11 @@
"is-extglob": "^2.1.1"
}
},
+ "is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw=="
+ },
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -4477,6 +4811,15 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
+ "lowlight": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
+ "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
+ "requires": {
+ "fault": "^1.0.0",
+ "highlight.js": "~10.7.0"
+ }
+ },
"mdast-util-definitions": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz",
@@ -4808,6 +5151,26 @@
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
"dev": true
},
+ "parse-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+ "requires": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ },
+ "dependencies": {
+ "character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw=="
+ }
+ }
+ },
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
@@ -4905,6 +5268,11 @@
"rrweb-snapshot": "^1.1.14"
}
},
+ "prismjs": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
+ },
"prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@@ -5004,6 +5372,18 @@
"prop-types": "^15.7.2"
}
},
+ "react-syntax-highlighter": {
+ "version": "15.5.0",
+ "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
+ "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "highlight.js": "^10.4.1",
+ "lowlight": "^1.17.0",
+ "prismjs": "^1.27.0",
+ "refractor": "^3.6.0"
+ }
+ },
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -5022,6 +5402,23 @@
"picomatch": "^2.2.1"
}
},
+ "refractor": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
+ "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
+ "requires": {
+ "hastscript": "^6.0.0",
+ "parse-entities": "^2.0.0",
+ "prismjs": "~1.27.0"
+ },
+ "dependencies": {
+ "prismjs": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
+ "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
+ }
+ }
+ },
"regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
@@ -5369,8 +5766,7 @@
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"yaml": {
"version": "1.10.2",
diff --git a/extension/react-app/package.json b/extension/react-app/package.json
index 230bd5b9..78dd12e4 100644
--- a/extension/react-app/package.json
+++ b/extension/react-app/package.json
@@ -13,17 +13,20 @@
"@types/vscode-webview": "^1.57.1",
"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",
"styled-components": "^5.3.6",
"vscode-webview": "^1.0.1-beta.1"
},
"devDependencies": {
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
+ "@types/react-syntax-highlighter": "^15.5.7",
"@types/styled-components": "^5.1.26",
"@vitejs/plugin-react-swc": "^3.0.0",
"autoprefixer": "^10.4.13",
diff --git a/extension/react-app/public/continue.gif b/extension/react-app/public/continue.gif
new file mode 100644
index 00000000..daed6663
--- /dev/null
+++ b/extension/react-app/public/continue.gif
Binary files differ
diff --git a/extension/react-app/src/components/CodeBlock.tsx b/extension/react-app/src/components/CodeBlock.tsx
index 0aae0bbb..b0de13ac 100644
--- a/extension/react-app/src/components/CodeBlock.tsx
+++ b/extension/react-app/src/components/CodeBlock.tsx
@@ -5,28 +5,27 @@ import { defaultBorderRadius, secondaryDark, vscBackground } from ".";
import { Clipboard, CheckCircle } from "@styled-icons/heroicons-outline";
+import StyledCode from "./StyledCode";
+
const StyledPre = styled.pre`
overflow-y: scroll;
word-wrap: normal;
border: 0.5px solid gray;
border-radius: ${defaultBorderRadius};
background-color: ${secondaryDark};
- padding: 8px;
- padding-top: 14px;
- padding-bottom: 16px;
+ position: relative;
`;
-const StyledCode = styled.code``;
+const CopyButtonDiv = styled.div`
+ position: absolute;
+ top: 4px;
+ right: 4px;
+`;
const StyledCopyButton = styled.button<{ visible: boolean }>`
- /* position: relative; */
- float: right;
border: none;
- background-color: ${secondaryDark};
+ background-color: transparent;
cursor: pointer;
- padding: 0;
- /* margin: 4px; */
- margin-top: -6px;
visibility: ${(props) => (props.visible ? "visible" : "hidden")};
`;
@@ -62,9 +61,55 @@ function CopyButton(props: { textToCopy: string; visible: boolean }) {
);
}
-function CodeBlock(props: { language?: string; children: string }) {
+function CodeBlock(props: { children: string }) {
+ const [result, setResult] = useState<AutoHighlightResult | undefined>(
+ undefined
+ );
useEffect(() => {
- hljs.highlightAll();
+ const result = hljs.highlightAuto(
+ (props.children as any).props.children[0],
+ [
+ "python",
+ "javascript",
+ "typescript",
+ "bash",
+ "html",
+ "css",
+ "json",
+ "yaml",
+ "markdown",
+ "sql",
+ "java",
+ "c",
+ "cpp",
+ "csharp",
+ "go",
+ "kotlin",
+ "php",
+ "ruby",
+ "rust",
+ "scala",
+ "swift",
+ "dart",
+ "haskell",
+ "perl",
+ "r",
+ "matlab",
+ "powershell",
+ "lua",
+ "elixir",
+ "clojure",
+ "groovy",
+ "julia",
+ "vbnet",
+ "objectivec",
+ "fsharp",
+ "erlang",
+ "ocaml",
+ ]
+ );
+ console.log(result);
+ setResult(result);
}, [props.children]);
const [hovered, setHovered] = useState<boolean>(false);
@@ -77,11 +122,15 @@ function CodeBlock(props: { language?: string; children: string }) {
setHovered(false);
}}
>
- <CopyButton
- visible={hovered}
- textToCopy={(props.children as any).props.children[0]}
- />
- <StyledCode>{props.children}</StyledCode>
+ <CopyButtonDiv>
+ <CopyButton
+ visible={hovered}
+ textToCopy={(props.children as any).props.children[0]}
+ />
+ </CopyButtonDiv>
+ <StyledCode language={result?.language}>
+ {(props.children as any).props.children[0]}
+ </StyledCode>
</StyledPre>
);
}
diff --git a/extension/react-app/src/components/ContinueButton.tsx b/extension/react-app/src/components/ContinueButton.tsx
index c6117bf9..ef6719b7 100644
--- a/extension/react-app/src/components/ContinueButton.tsx
+++ b/extension/react-app/src/components/ContinueButton.tsx
@@ -1,6 +1,8 @@
import styled, { keyframes } from "styled-components";
import { Button } from ".";
import { Play } from "@styled-icons/heroicons-outline";
+import { useSelector } from "react-redux";
+import { RootStore } from "../redux/store";
let StyledButton = styled(Button)`
margin: auto;
@@ -25,14 +27,21 @@ let StyledButton = styled(Button)`
`;
function ContinueButton(props: { onClick?: () => void; hidden?: boolean }) {
+ const vscMediaUrl = useSelector(
+ (state: RootStore) => state.config.vscMediaUrl
+ );
+
return (
<StyledButton
hidden={props.hidden}
className="m-auto"
onClick={props.onClick}
>
- <Play />
- {/* <img src={"/continue_arrow.png"} width="16px"></img> */}
+ {vscMediaUrl ? (
+ <img src={`${vscMediaUrl}/play_button.png`} width="22px" />
+ ) : (
+ <Play />
+ )}
Continue
</StyledButton>
);
diff --git a/extension/react-app/src/components/DebugPanel.tsx b/extension/react-app/src/components/DebugPanel.tsx
index 30f38779..94dbac9e 100644
--- a/extension/react-app/src/components/DebugPanel.tsx
+++ b/extension/react-app/src/components/DebugPanel.tsx
@@ -6,6 +6,7 @@ import {
setApiUrl,
setVscMachineId,
setSessionId,
+ setVscMediaUrl,
} from "../redux/slices/configSlice";
import { setHighlightedCode } from "../redux/slices/miscSlice";
import { updateFileSystem } from "../redux/slices/debugContexSlice";
@@ -37,6 +38,7 @@ function DebugPanel(props: DebugPanelProps) {
dispatch(setApiUrl(event.data.apiUrl));
dispatch(setVscMachineId(event.data.vscMachineId));
dispatch(setSessionId(event.data.sessionId));
+ dispatch(setVscMediaUrl(event.data.vscMediaUrl));
break;
case "highlightedCode":
dispatch(setHighlightedCode(event.data.rangeInFile));
diff --git a/extension/react-app/src/components/HeaderButtonWithText.tsx b/extension/react-app/src/components/HeaderButtonWithText.tsx
index acaca9ce..30931f86 100644
--- a/extension/react-app/src/components/HeaderButtonWithText.tsx
+++ b/extension/react-app/src/components/HeaderButtonWithText.tsx
@@ -6,14 +6,20 @@ interface HeaderButtonWithTextProps {
text: string;
onClick?: (e: any) => void;
children: React.ReactNode;
+ disabled?: boolean;
}
const HeaderButtonWithText = (props: HeaderButtonWithTextProps) => {
const [hover, setHover] = useState(false);
return (
<HeaderButton
+ disabled={props.disabled}
style={{ padding: "1px", paddingLeft: hover ? "4px" : "1px" }}
- onMouseEnter={() => setHover(true)}
+ onMouseEnter={() => {
+ if (!props.disabled) {
+ setHover(true);
+ }
+ }}
onMouseLeave={() => {
setHover(false);
}}
diff --git a/extension/react-app/src/components/LoadingCover.tsx b/extension/react-app/src/components/LoadingCover.tsx
new file mode 100644
index 00000000..a0f8f7a2
--- /dev/null
+++ b/extension/react-app/src/components/LoadingCover.tsx
@@ -0,0 +1,50 @@
+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/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index 74a1c4e8..827d2d5f 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -200,6 +200,7 @@ function StepContainer(props: StepContainerProps) {
<>
<HeaderButtonWithText
+ disabled={props.historyNode.active as boolean}
onClick={(e) => {
e.stopPropagation();
props.onDelete();
diff --git a/extension/react-app/src/components/StyledCode.tsx b/extension/react-app/src/components/StyledCode.tsx
new file mode 100644
index 00000000..c5ed0101
--- /dev/null
+++ b/extension/react-app/src/components/StyledCode.tsx
@@ -0,0 +1,19 @@
+import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
+import { vscDarkPlus as highlightStyle } from "react-syntax-highlighter/dist/esm/styles/prism";
+
+interface StyledCodeProps {
+ children: string;
+ language?: string;
+}
+
+const StyledCode = (props: StyledCodeProps) => (
+ <SyntaxHighlighter
+ customStyle={{ margin: "0" }}
+ style={highlightStyle}
+ language={props.language || "python"}
+ >
+ {props.children}
+ </SyntaxHighlighter>
+);
+
+export default StyledCode;
diff --git a/extension/react-app/src/components/TextDialog.tsx b/extension/react-app/src/components/TextDialog.tsx
index e50a7686..2632e572 100644
--- a/extension/react-app/src/components/TextDialog.tsx
+++ b/extension/react-app/src/components/TextDialog.tsx
@@ -15,6 +15,7 @@ const DialogContainer = styled.div`
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
+ width: 75%;
`;
const Dialog = styled.div`
@@ -76,7 +77,6 @@ const TextDialog = (props: {
<Dialog>
<P>Thanks for your feedback. We'll get back to you soon!</P>
<TextArea
- cols={50}
rows={10}
ref={textAreaRef}
onKeyDown={(e) => {
diff --git a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
index 824bb086..3d8e0a38 100644
--- a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
+++ b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
@@ -13,6 +13,8 @@ abstract class AbstractContinueGUIClientProtocol {
callback: (commands: { name: string; description: string }[]) => void
): void;
+ abstract changeDefaultModel(model: string): void;
+
abstract sendClear(): void;
abstract retryAtIndex(index: number): void;
diff --git a/extension/react-app/src/hooks/useContinueGUIProtocol.ts b/extension/react-app/src/hooks/useContinueGUIProtocol.ts
index 59397742..f43a66ff 100644
--- a/extension/react-app/src/hooks/useContinueGUIProtocol.ts
+++ b/extension/react-app/src/hooks/useContinueGUIProtocol.ts
@@ -55,6 +55,10 @@ class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol {
});
}
+ changeDefaultModel(model: string) {
+ this.messenger.send("change_default_model", { model });
+ }
+
sendClear() {
this.messenger.send("clear_history", {});
}
diff --git a/extension/react-app/src/redux/slices/configSlice.ts b/extension/react-app/src/redux/slices/configSlice.ts
index a6a641e6..1b107bed 100644
--- a/extension/react-app/src/redux/slices/configSlice.ts
+++ b/extension/react-app/src/redux/slices/configSlice.ts
@@ -37,9 +37,21 @@ export const configSlice = createSlice({
...state,
sessionId: action.payload,
}),
+ setVscMediaUrl: (
+ state: RootStore["config"],
+ action: { type: string; payload: string }
+ ) => ({
+ ...state,
+ vscMediaUrl: action.payload,
+ }),
},
});
-export const { setVscMachineId, setApiUrl, setWorkspacePath, setSessionId } =
- configSlice.actions;
+export const {
+ setVscMachineId,
+ setApiUrl,
+ setWorkspacePath,
+ setSessionId,
+ setVscMediaUrl,
+} = configSlice.actions;
export default configSlice.reducer;
diff --git a/extension/react-app/src/redux/store.ts b/extension/react-app/src/redux/store.ts
index f9eb0517..a5eef4ba 100644
--- a/extension/react-app/src/redux/store.ts
+++ b/extension/react-app/src/redux/store.ts
@@ -21,6 +21,7 @@ export interface RootStore {
vscMachineId: string | undefined;
sessionId: string | undefined;
sessionStarted: number | undefined;
+ vscMediaUrl: string | undefined;
};
chat: {
messages: ChatMessage[];
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index f0e3ffd4..13b74423 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -18,6 +18,7 @@ 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";
const TopGUIDiv = styled.div`
overflow: hidden;
@@ -215,7 +216,7 @@ function GUI(props: GUIProps) {
useEffect(() => {
const listener = (e: any) => {
// Cmd + J to toggle fast model
- if (e.key === "j" && e.metaKey) {
+ if (e.key === "i" && e.metaKey && e.shiftKey) {
setUsingFastModel((prev) => !prev);
}
};
@@ -230,21 +231,24 @@ function GUI(props: GUIProps) {
console.log("CLIENT ON STATE UPDATE: ", client, client?.onStateUpdate);
client?.onStateUpdate((state) => {
// Scroll only if user is at very bottom of the window.
+ setUsingFastModel(state.default_model === "gpt-3.5-turbo");
const shouldScrollToBottom =
topGuiDivRef.current &&
topGuiDivRef.current?.offsetHeight - window.scrollY < 100;
setWaitingForSteps(state.active);
setHistory(state.history);
setUserInputQueue(state.user_input_queue);
- const nextStepsOpen = [...stepsOpen];
- for (
- let i = nextStepsOpen.length;
- i < state.history.timeline.length;
- i++
- ) {
- nextStepsOpen.push(true);
- }
- setStepsOpen(nextStepsOpen);
+ setStepsOpen((prev) => {
+ const nextStepsOpen = [...prev];
+ for (
+ let i = nextStepsOpen.length;
+ i < state.history.timeline.length;
+ i++
+ ) {
+ nextStepsOpen.push(true);
+ }
+ return nextStepsOpen;
+ });
if (shouldScrollToBottom) {
scrollToBottom();
@@ -325,6 +329,7 @@ function GUI(props: GUIProps) {
// const iterations = useSelector(selectIterations);
return (
<>
+ <LoadingCover hidden={true} message="Downloading local model..." />
<TextDialog
showDialog={showFeedbackDialog}
onEnter={(text) => {
@@ -347,9 +352,7 @@ function GUI(props: GUIProps) {
{typeof client === "undefined" && (
<>
<Loader></Loader>
- <p style={{ textAlign: "center" }}>
- Trying to reconnect with server...
- </p>
+ <p style={{ textAlign: "center" }}>Loading Continue server...</p>
</>
)}
{history?.timeline.map((node: HistoryNode, index: number) => {
@@ -388,7 +391,7 @@ function GUI(props: GUIProps) {
/>
);
})}
- {/* {waitingForSteps && <Loader></Loader>} */}
+ {waitingForSteps && <Loader></Loader>}
<div>
{userInputQueue.map((input) => {
@@ -426,9 +429,9 @@ function GUI(props: GUIProps) {
}}
hidden={!showDataSharingInfo}
>
- By turning on this switch, you signal that you would
- contribute this software development data to a publicly
- accessible, open-source dataset in the future.
+ By turning on this switch, you signal that you would contribute this
+ software development data to a publicly accessible, open-source dataset
+ in the future.
<br />
<br />
<b>
@@ -470,8 +473,11 @@ function GUI(props: GUIProps) {
Contribute Data
</span>
</div>
- {/* <HeaderButtonWithText
+ <HeaderButtonWithText
onClick={() => {
+ client?.changeDefaultModel(
+ usingFastModel ? "gpt-4" : "gpt-3.5-turbo"
+ );
setUsingFastModel((prev) => !prev);
}}
text={usingFastModel ? "gpt-3.5-turbo" : "gpt-4"}
@@ -481,7 +487,7 @@ function GUI(props: GUIProps) {
>
{usingFastModel ? "⚡" : "🧠"}
</div>
- </HeaderButtonWithText> */}
+ </HeaderButtonWithText>
<HeaderButtonWithText
onClick={() => {
client?.sendClear();
diff --git a/extension/schema/History.d.ts b/extension/schema/History.d.ts
index 508deaf0..6eb8ad81 100644
--- a/extension/schema/History.d.ts
+++ b/extension/schema/History.d.ts
@@ -8,8 +8,19 @@
export type History = History1;
export type Name = string;
export type Hide = boolean;
+export type Description = string;
export type SystemMessage = string;
+export type Role = "assistant" | "user" | "system" | "function";
+export type Content = string;
+export type Name1 = string;
+export type Summary = string;
+export type Name2 = string;
+export type Arguments = string;
+export type ChatContext = ChatMessage[];
+export type ManageOwnChatContext = boolean;
export type Depth = number;
+export type Deleted = boolean;
+export type Active = boolean;
export type Timeline = HistoryNode[];
export type CurrentIndex = number;
@@ -28,12 +39,30 @@ export interface HistoryNode {
step: Step;
observation?: Observation;
depth: Depth;
+ deleted?: Deleted;
+ active?: Active;
[k: string]: unknown;
}
export interface Step {
name?: Name;
hide?: Hide;
+ description?: Description;
system_message?: SystemMessage;
+ chat_context?: ChatContext;
+ manage_own_chat_context?: ManageOwnChatContext;
+ [k: string]: unknown;
+}
+export interface ChatMessage {
+ role: Role;
+ content?: Content;
+ name?: Name1;
+ summary: Summary;
+ function_call?: FunctionCall;
+ [k: string]: unknown;
+}
+export interface FunctionCall {
+ name: Name2;
+ arguments: Arguments;
[k: string]: unknown;
}
export interface Observation {
diff --git a/extension/schema/HistoryNode.d.ts b/extension/schema/HistoryNode.d.ts
index c1507270..bc77be89 100644
--- a/extension/schema/HistoryNode.d.ts
+++ b/extension/schema/HistoryNode.d.ts
@@ -8,8 +8,19 @@
export type HistoryNode = HistoryNode1;
export type Name = string;
export type Hide = boolean;
+export type Description = string;
export type SystemMessage = string;
+export type Role = "assistant" | "user" | "system" | "function";
+export type Content = string;
+export type Name1 = string;
+export type Summary = string;
+export type Name2 = string;
+export type Arguments = string;
+export type ChatContext = ChatMessage[];
+export type ManageOwnChatContext = boolean;
export type Depth = number;
+export type Deleted = boolean;
+export type Active = boolean;
/**
* A point in history, a list of which make up History
@@ -18,12 +29,30 @@ export interface HistoryNode1 {
step: Step;
observation?: Observation;
depth: Depth;
+ deleted?: Deleted;
+ active?: Active;
[k: string]: unknown;
}
export interface Step {
name?: Name;
hide?: Hide;
+ description?: Description;
system_message?: SystemMessage;
+ chat_context?: ChatContext;
+ manage_own_chat_context?: ManageOwnChatContext;
+ [k: string]: unknown;
+}
+export interface ChatMessage {
+ role: Role;
+ content?: Content;
+ name?: Name1;
+ summary: Summary;
+ function_call?: FunctionCall;
+ [k: string]: unknown;
+}
+export interface FunctionCall {
+ name: Name2;
+ arguments: Arguments;
[k: string]: unknown;
}
export interface Observation {
diff --git a/extension/scripts/.gitignore b/extension/scripts/.gitignore
index 7af27c08..fbb3bf9f 100644
--- a/extension/scripts/.gitignore
+++ b/extension/scripts/.gitignore
@@ -1,3 +1,5 @@
testdb
env
-stdout.txt \ No newline at end of file
+stdout.txt
+.continue_env_installed
+**.whl \ No newline at end of file
diff --git a/extension/scripts/continuedev-0.1.1-py3-none-any.whl b/extension/scripts/continuedev-0.1.1-py3-none-any.whl
deleted file mode 100644
index 99f96d80..00000000
--- a/extension/scripts/continuedev-0.1.1-py3-none-any.whl
+++ /dev/null
Binary files differ
diff --git a/extension/src/activation/activate.ts b/extension/src/activation/activate.ts
index 32726c86..0c92f095 100644
--- a/extension/src/activation/activate.ts
+++ b/extension/src/activation/activate.ts
@@ -2,30 +2,31 @@ import * as vscode from "vscode";
import { registerAllCommands } from "../commands";
import { registerAllCodeLensProviders } from "../lang-server/codeLens";
import { sendTelemetryEvent, TelemetryEvent } from "../telemetry";
-import { getExtensionUri } from "../util/vscode";
-import * as path from "path";
// import { openCapturedTerminal } from "../terminal/terminalEmulator";
import IdeProtocolClient from "../continueIdeClient";
import { getContinueServerUrl } from "../bridge";
-import { setupDebugPanel, ContinueGUIWebviewViewProvider } from "../debugPanel";
import { CapturedTerminal } from "../terminal/terminalEmulator";
+import { setupDebugPanel, ContinueGUIWebviewViewProvider } from "../debugPanel";
+import { startContinuePythonServer } from "./environmentSetup";
+// import { CapturedTerminal } from "../terminal/terminalEmulator";
export let extensionContext: vscode.ExtensionContext | undefined = undefined;
export let ideProtocolClient: IdeProtocolClient;
-export function activateExtension(
+export async function activateExtension(
context: vscode.ExtensionContext,
showTutorial: boolean
) {
- sendTelemetryEvent(TelemetryEvent.ExtensionActivated);
+ extensionContext = context;
+ sendTelemetryEvent(TelemetryEvent.ExtensionActivated);
registerAllCodeLensProviders(context);
registerAllCommands(context);
// vscode.window.registerWebviewViewProvider("continue.continueGUIView", setupDebugPanel);
-
- let serverUrl = getContinueServerUrl();
+ await startContinuePythonServer();
+ const serverUrl = getContinueServerUrl();
ideProtocolClient = new IdeProtocolClient(
`${serverUrl.replace("http", "ws")}/ide/ws`,
@@ -49,41 +50,8 @@ export function activateExtension(
})();
// All opened terminals should be replaced by our own terminal
- vscode.window.onDidOpenTerminal((terminal) => {
- if (terminal.name === "Continue") {
- return;
- }
- const options = terminal.creationOptions;
- const capturedTerminal = new CapturedTerminal({
- ...options,
- name: "Continue",
- });
- terminal.dispose();
- if (!ideProtocolClient.continueTerminal) {
- ideProtocolClient.continueTerminal = capturedTerminal;
- }
- });
+ // vscode.window.onDidOpenTerminal((terminal) => {});
// If any terminals are open to start, replace them
- vscode.window.terminals.forEach((terminal) => {
- if (terminal.name === "Continue") {
- return;
- }
- const options = terminal.creationOptions;
- const capturedTerminal = new CapturedTerminal(
- {
- ...options,
- name: "Continue",
- },
- (commandOutput: string) => {
- ideProtocolClient.sendCommandOutput(commandOutput);
- }
- );
- terminal.dispose();
- if (!ideProtocolClient.continueTerminal) {
- ideProtocolClient.continueTerminal = capturedTerminal;
- }
- });
-
- extensionContext = context;
+ // vscode.window.terminals.forEach((terminal) => {}
}
diff --git a/extension/src/activation/environmentSetup.ts b/extension/src/activation/environmentSetup.ts
index cdaf3ac0..ec0e228d 100644
--- a/extension/src/activation/environmentSetup.ts
+++ b/extension/src/activation/environmentSetup.ts
@@ -7,6 +7,25 @@ import * as fs from "fs";
import rebuild from "@electron/rebuild";
import { getContinueServerUrl } from "../bridge";
import fetch from "node-fetch";
+import * as vscode from "vscode";
+
+const MAX_RETRIES = 5;
+async function retryThenFail(
+ fn: () => Promise<any>,
+ retries: number = MAX_RETRIES
+): Promise<any> {
+ try {
+ return await fn();
+ } catch (e) {
+ if (retries > 0) {
+ return await retryThenFail(fn, retries - 1);
+ }
+ vscode.window.showErrorMessage(
+ "Failed to set up Continue extension. Please email nate@continue.dev and we'll get this fixed ASAP!"
+ );
+ throw e;
+ }
+}
async function runCommand(cmd: string): Promise<[string, string | undefined]> {
console.log("Running command: ", cmd);
@@ -52,14 +71,16 @@ async function getPythonPipCommands() {
return [pythonCmd, pipCmd];
}
-function getActivateUpgradeCommands(pythonCmd: string, pipCmd: string) {
+function getActivateUpgradeTouchCommands(pythonCmd: string, pipCmd: string) {
let activateCmd = ". env/bin/activate";
let pipUpgradeCmd = `${pipCmd} install --upgrade pip`;
+ let touchCmd = "touch .continue_env_installed";
if (process.platform == "win32") {
activateCmd = ".\\env\\Scripts\\activate";
pipUpgradeCmd = `${pythonCmd} -m pip install --upgrade pip`;
+ touchCmd = "ni .continue_env_installed -type file";
}
- return [activateCmd, pipUpgradeCmd];
+ return [activateCmd, pipUpgradeCmd, touchCmd];
}
function checkEnvExists() {
@@ -77,55 +98,69 @@ function checkEnvExists() {
);
}
+function checkRequirementsInstalled() {
+ return fs.existsSync(
+ path.join(getExtensionUri().fsPath, "scripts", ".continue_env_installed")
+ );
+}
+
async function setupPythonEnv() {
console.log("Setting up python env for Continue extension...");
- if (checkEnvExists()) return;
-
- // Assemble the command to create the env
const [pythonCmd, pipCmd] = await getPythonPipCommands();
- const [activateCmd, pipUpgradeCmd] = getActivateUpgradeCommands(
- pythonCmd,
- pipCmd
- );
- const createEnvCommand = [
- `cd ${path.join(getExtensionUri().fsPath, "scripts")}`,
- `${pythonCmd} -m venv env`,
- ].join("; ");
+ const [activateCmd, pipUpgradeCmd, touchCmd] =
+ getActivateUpgradeTouchCommands(pythonCmd, pipCmd);
- // Repeat until it is successfully created (sometimes it fails to generate the bin, need to try again)
- while (true) {
- const [, stderr] = await runCommand(createEnvCommand);
- if (stderr) {
- throw new Error(stderr);
- }
- if (checkEnvExists()) {
- break;
- } else {
- // Remove the env and try again
- const removeCommand = `rm -rf ${path.join(
- getExtensionUri().fsPath,
- "scripts",
- "env"
- )}`;
- await runCommand(removeCommand);
+ if (checkEnvExists()) {
+ console.log("Python env already exists, skipping...");
+ } else {
+ // Assemble the command to create the env
+ const createEnvCommand = [
+ `cd "${path.join(getExtensionUri().fsPath, "scripts")}"`,
+ `${pythonCmd} -m venv env`,
+ ].join(" ; ");
+
+ // Repeat until it is successfully created (sometimes it fails to generate the bin, need to try again)
+ while (true) {
+ const [, stderr] = await runCommand(createEnvCommand);
+ if (stderr) {
+ throw new Error(stderr);
+ }
+ if (checkEnvExists()) {
+ break;
+ } else {
+ // Remove the env and try again
+ const removeCommand = `rm -rf "${path.join(
+ getExtensionUri().fsPath,
+ "scripts",
+ "env"
+ )}"`;
+ await runCommand(removeCommand);
+ }
}
+ console.log(
+ "Successfully set up python env at ",
+ getExtensionUri().fsPath + "/scripts/env"
+ );
}
- console.log(
- "Successfully set up python env at ",
- getExtensionUri().fsPath + "/scripts/env"
- );
- const installRequirementsCommand = [
- `cd ${path.join(getExtensionUri().fsPath, "scripts")}`,
- activateCmd,
- pipUpgradeCmd,
- `${pipCmd} install -r requirements.txt`,
- ].join(" ; ");
- const [, stderr] = await runCommand(installRequirementsCommand);
- if (stderr) {
- throw new Error(stderr);
- }
+ await retryThenFail(async () => {
+ if (checkRequirementsInstalled()) {
+ console.log("Python requirements already installed, skipping...");
+ } else {
+ const installRequirementsCommand = [
+ `cd "${path.join(getExtensionUri().fsPath, "scripts")}"`,
+ activateCmd,
+ pipUpgradeCmd,
+ `${pipCmd} install -r requirements.txt`,
+ touchCmd,
+ ].join(" ; ");
+ const [, stderr] = await runCommand(installRequirementsCommand);
+ if (stderr) {
+ throw new Error(stderr);
+ }
+ }
+ });
}
function readEnvFile(path: string) {
@@ -180,15 +215,11 @@ export async function startContinuePythonServer() {
await setupPythonEnv();
// Check vscode settings
- let serverUrl = getContinueServerUrl();
+ const serverUrl = getContinueServerUrl();
if (serverUrl !== "http://localhost:8000") {
return;
}
- console.log("Starting Continue python server...");
-
- if (await checkServerRunning(serverUrl)) return;
-
let activateCmd = ". env/bin/activate";
let pythonCmd = "python3";
if (process.platform == "win32") {
@@ -196,38 +227,44 @@ export async function startContinuePythonServer() {
pythonCmd = "python";
}
- let command = `cd ${path.join(
+ let command = `cd "${path.join(
getExtensionUri().fsPath,
"scripts"
- )} && ${activateCmd} && cd .. && ${pythonCmd} -m scripts.run_continue_server`;
+ )}" && ${activateCmd} && cd .. && ${pythonCmd} -m scripts.run_continue_server`;
+
+ return await retryThenFail(async () => {
+ console.log("Starting Continue python server...");
- return new Promise(async (resolve, reject) => {
- try {
- const child = spawn(command, {
- shell: true,
- });
- child.stdout.on("data", (data: any) => {
- console.log(`stdout: ${data}`);
- });
- child.stderr.on("data", (data: any) => {
- console.log(`stderr: ${data}`);
- if (data.includes("Uvicorn running on")) {
- console.log("Successfully started Continue python server");
+ if (await checkServerRunning(serverUrl)) return;
+
+ return new Promise(async (resolve, reject) => {
+ try {
+ const child = spawn(command, {
+ shell: true,
+ });
+ child.stdout.on("data", (data: any) => {
+ console.log(`stdout: ${data}`);
+ });
+ child.stderr.on("data", (data: any) => {
+ console.log(`stderr: ${data}`);
+ if (data.includes("Uvicorn running on")) {
+ console.log("Successfully started Continue python server");
+ resolve(null);
+ }
+ });
+ child.on("error", (error: any) => {
+ console.log(`error: ${error.message}`);
+ });
+ } catch (e) {
+ console.log("Failed to start Continue python server", e);
+ // If failed, check if it's because the server is already running (might have happened just after we checked above)
+ if (await checkServerRunning(serverUrl)) {
resolve(null);
+ } else {
+ reject();
}
- });
- child.on("error", (error: any) => {
- console.log(`error: ${error.message}`);
- });
- } catch (e) {
- console.log("Failed to start Continue python server", e);
- // If failed, check if it's because the server is already running (might have happened just after we checked above)
- if (await checkServerRunning(serverUrl)) {
- resolve(null);
- } else {
- reject();
}
- }
+ });
});
}
diff --git a/extension/src/commands.ts b/extension/src/commands.ts
index 424c238a..8072353b 100644
--- a/extension/src/commands.ts
+++ b/extension/src/commands.ts
@@ -3,7 +3,6 @@ import {
decorationManager,
showAnswerInTextEditor,
showGutterSpinner,
- writeAndShowUnitTest,
} from "./decorations";
import {
acceptSuggestionCommand,
@@ -14,19 +13,8 @@ import {
rejectAllSuggestionsCommand,
} from "./suggestions";
import * as bridge from "./bridge";
-import { debugPanelWebview, setupDebugPanel } from "./debugPanel";
-// import { openCapturedTerminal } from "./terminal/terminalEmulator";
-import { getRightViewColumn } from "./util/vscode";
-import {
- findSuspiciousCode,
- runPythonScript,
- writeUnitTestForFunction,
-} from "./bridge";
+import { debugPanelWebview } from "./debugPanel";
import { sendTelemetryEvent, TelemetryEvent } from "./telemetry";
-import { getLanguageLibrary } from "./languages";
-import { SerializedDebugContext } from "./client";
-import { addFileSystemToDebugContext } from "./util/util";
-import { ideProtocolClient } from "./activation/activate";
// Copy everything over from extension.ts
const commandsMap: { [command: string]: (...args: any) => any } = {
@@ -71,72 +59,9 @@ const commandsMap: { [command: string]: (...args: any) => any } = {
type: "focusContinueInput",
});
},
- "continue.openCapturedTerminal": () => {
- // Happens in webview resolution function
- // openCapturedTerminal();
- },
- "continue.findSuspiciousCode": async (
- debugContext: SerializedDebugContext
- ) => {
- vscode.window.withProgress(
- {
- location: vscode.ProgressLocation.Notification,
- title: "Finding suspicious code",
- cancellable: false,
- },
- async (progress, token) => {
- let suspiciousCode = await findSuspiciousCode(debugContext);
- debugContext.rangesInFiles = suspiciousCode;
- let { filesystem } = addFileSystemToDebugContext(debugContext);
- debugPanelWebview?.postMessage({
- type: "findSuspiciousCode",
- codeLocations: suspiciousCode,
- filesystem,
- });
- }
- );
- },
- "continue.debugTest": async (fileAndFunctionSpecifier: string) => {
- sendTelemetryEvent(TelemetryEvent.AutoDebugThisTest);
- let editor = vscode.window.activeTextEditor;
- if (editor) editor.document.save();
- let { stdout } = await runPythonScript("run_unit_test.py", [
- fileAndFunctionSpecifier,
- ]);
- let traceback = getLanguageLibrary(
- fileAndFunctionSpecifier.split("::")[0]
- ).parseFirstStacktrace(stdout);
- if (!traceback) {
- vscode.window.showInformationMessage("The test passes!");
- return;
- }
- vscode.commands.executeCommand("continue.openContinueGUI").then(() => {
- setTimeout(() => {
- debugPanelWebview?.postMessage({
- type: "traceback",
- value: traceback,
- });
- }, 500);
- });
- },
};
const textEditorCommandsMap: { [command: string]: (...args: any) => {} } = {
- "continue.writeUnitTest": async (editor: vscode.TextEditor) => {
- let position = editor.selection.active;
-
- let gutterSpinnerKey = showGutterSpinner(editor, position.line);
- try {
- let test = await writeUnitTestForFunction(
- editor.document.fileName,
- position
- );
- writeAndShowUnitTest(editor.document.fileName, test);
- } catch {
- } finally {
- decorationManager.deleteDecoration(gutterSpinnerKey);
- }
- },
"continue.writeDocstring": async (editor: vscode.TextEditor, _) => {
sendTelemetryEvent(TelemetryEvent.GenerateDocstring);
let gutterSpinnerKey = showGutterSpinner(
@@ -203,20 +128,3 @@ async function answerQuestion(
}
);
}
-
-// async function suggestFixForAllWorkspaceProblems() {
-// Something like this, just figure out the loops for diagnostics vs problems
-// let problems = vscode.languages.getDiagnostics();
-// let codeSuggestions = await Promise.all(problems.map((problem) => {
-// return bridge.suggestFixForProblem(problem[0].fsPath, problem[1]);
-// }));
-// for (const [uri, diagnostics] of problems) {
-// for (let i = 0; i < diagnostics.length; i++) {
-// let diagnostic = diagnostics[i];
-// let suggestedCode = codeSuggestions[i];
-// // If you're going to do this for a bunch of files at once, it will show the unsaved icon in the tab
-// // BUT it would be better to have a single window to review all edits
-// showSuggestion(uri.fsPath, diagnostic.range, suggestedCode)
-// }
-// }
-// }
diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts
index 877d9f3e..8ab3e075 100644
--- a/extension/src/continueIdeClient.ts
+++ b/extension/src/continueIdeClient.ts
@@ -15,7 +15,6 @@ import { debugPanelWebview, setupDebugPanel } from "./debugPanel";
import { FileEditWithFullContents } from "../schema/FileEditWithFullContents";
import fs = require("fs");
import { WebsocketMessenger } from "./util/messenger";
-import { CapturedTerminal } from "./terminal/terminalEmulator";
import { decorationManager } from "./decorations";
class IdeProtocolClient {
@@ -334,17 +333,14 @@ class IdeProtocolClient {
return rangeInFiles;
}
- public continueTerminal: CapturedTerminal | undefined;
-
async runCommand(command: string) {
- if (!this.continueTerminal || this.continueTerminal.isClosed()) {
- this.continueTerminal = new CapturedTerminal({
- name: "Continue",
- });
+ if (vscode.window.terminals.length) {
+ vscode.window.terminals[0].sendText(command);
+ } else {
+ const terminal = vscode.window.createTerminal();
+ terminal.show();
+ terminal.sendText(command);
}
-
- this.continueTerminal.show();
- return await this.continueTerminal.runCommand(command);
}
sendCommandOutput(output: string) {
diff --git a/extension/src/debugPanel.ts b/extension/src/debugPanel.ts
index bb98eb46..b0db590a 100644
--- a/extension/src/debugPanel.ts
+++ b/extension/src/debugPanel.ts
@@ -1,21 +1,11 @@
import * as vscode from "vscode";
-import {
- debugApi,
- getContinueServerUrl,
- runPythonScript,
- unittestApi,
-} from "./bridge";
-import { writeAndShowUnitTest } from "./decorations";
-import { showSuggestion } from "./suggestions";
-import { getLanguageLibrary } from "./languages";
+import { getContinueServerUrl } from "./bridge";
import {
getExtensionUri,
getNonce,
openEditorAndRevealRange,
} from "./util/vscode";
-import { sendTelemetryEvent, TelemetryEvent } from "./telemetry";
-import { RangeInFile, SerializedDebugContext } from "./client";
-import { addFileSystemToDebugContext } from "./util/util";
+import { RangeInFile } from "./client";
const WebSocket = require("ws");
class StreamManager {
@@ -146,6 +136,9 @@ export function setupDebugPanel(
let extensionUri = getExtensionUri();
let scriptUri: string;
let styleMainUri: string;
+ let vscMediaUrl: string = debugPanelWebview
+ .asWebviewUri(vscode.Uri.joinPath(extensionUri, "react-app/dist"))
+ .toString();
const isProduction = true; // context?.extensionMode === vscode.ExtensionMode.Development;
if (!isProduction) {
@@ -236,6 +229,7 @@ export function setupDebugPanel(
vscMachineId: vscode.env.machineId,
apiUrl: getContinueServerUrl(),
sessionId,
+ vscMediaUrl,
});
// // Listen for changes to server URL in settings
@@ -273,71 +267,6 @@ export function setupDebugPanel(
connection.send(data.message);
break;
}
- case "listTenThings": {
- sendTelemetryEvent(TelemetryEvent.GenerateIdeas);
- let resp = await debugApi.listtenDebugListPost({
- serializedDebugContext: data.debugContext,
- });
- panel.webview.postMessage({
- type: "listTenThings",
- value: resp.completion,
- });
- break;
- }
- case "suggestFix": {
- let completion: string;
- let codeSelection = data.debugContext.rangesInFiles?.at(0);
- if (codeSelection) {
- completion = (
- await debugApi.inlineDebugInlinePost({
- inlineBody: {
- filecontents: await vscode.workspace.fs
- .readFile(vscode.Uri.file(codeSelection.filepath))
- .toString(),
- startline: codeSelection.range.start.line,
- endline: codeSelection.range.end.line,
- traceback: data.debugContext.traceback,
- },
- })
- ).completion;
- } else if (data.debugContext.traceback) {
- completion = (
- await debugApi.suggestionDebugSuggestionGet({
- traceback: data.debugContext.traceback,
- })
- ).completion;
- } else {
- break;
- }
- panel.webview.postMessage({
- type: "suggestFix",
- value: completion,
- });
- break;
- }
- case "findSuspiciousCode": {
- let traceback = getLanguageLibrary(".py").parseFirstStacktrace(
- data.debugContext.traceback
- );
- if (traceback === undefined) return;
- vscode.commands.executeCommand(
- "continue.findSuspiciousCode",
- data.debugContext
- );
- break;
- }
- case "queryEmbeddings": {
- let { results } = await runPythonScript("index.py query", [
- data.query,
- 2,
- vscode.workspace.workspaceFolders?.[0].uri.fsPath,
- ]);
- panel.webview.postMessage({
- type: "queryEmbeddings",
- results,
- });
- break;
- }
case "openFile": {
openEditorAndRevealRange(data.path, undefined, vscode.ViewColumn.One);
break;
@@ -351,20 +280,6 @@ export function setupDebugPanel(
streamManager.closeStream();
break;
}
- case "explainCode": {
- sendTelemetryEvent(TelemetryEvent.ExplainCode);
- let debugContext: SerializedDebugContext = addFileSystemToDebugContext(
- data.debugContext
- );
- let resp = await debugApi.explainDebugExplainPost({
- serializedDebugContext: debugContext,
- });
- panel.webview.postMessage({
- type: "explainCode",
- value: resp.completion,
- });
- break;
- }
case "withProgress": {
// This message allows withProgress to be used in the webview
if (data.done) {
@@ -395,83 +310,6 @@ export function setupDebugPanel(
);
break;
}
- case "makeEdit": {
- sendTelemetryEvent(TelemetryEvent.SuggestFix);
- let suggestedEdits = data.edits;
-
- if (
- typeof suggestedEdits === "undefined" ||
- suggestedEdits.length === 0
- ) {
- vscode.window.showInformationMessage(
- "Continue couldn't find a fix for this error."
- );
- return;
- }
-
- for (let i = 0; i < suggestedEdits.length; i++) {
- let edit = suggestedEdits[i];
- await showSuggestion(
- edit.filepath,
- new vscode.Range(
- edit.range.start.line,
- edit.range.start.character,
- edit.range.end.line,
- edit.range.end.character
- ),
- edit.replacement
- );
- }
- break;
- }
- case "generateUnitTest": {
- sendTelemetryEvent(TelemetryEvent.CreateTest);
- vscode.window.withProgress(
- {
- location: vscode.ProgressLocation.Notification,
- title: "Generating Unit Test...",
- cancellable: false,
- },
- async () => {
- for (let i = 0; i < data.debugContext.rangesInFiles?.length; i++) {
- let codeSelection = data.debugContext.rangesInFiles?.at(i);
- if (
- codeSelection &&
- codeSelection.filepath &&
- codeSelection.range
- ) {
- try {
- let filecontents = (
- await vscode.workspace.fs.readFile(
- vscode.Uri.file(codeSelection.filepath)
- )
- ).toString();
- let resp =
- await unittestApi.failingtestUnittestFailingtestPost({
- failingTestBody: {
- fp: {
- filecontents,
- lineno: codeSelection.range.end.line,
- },
- description: data.debugContext.description || "",
- },
- });
-
- if (resp.completion) {
- let decorationKey = await writeAndShowUnitTest(
- codeSelection.filepath,
- resp.completion
- );
- break;
- }
- } catch {}
- }
- }
- }
- );
-
- break;
- }
}
});
diff --git a/extension/src/decorations.ts b/extension/src/decorations.ts
index d2c94135..0587110c 100644
--- a/extension/src/decorations.ts
+++ b/extension/src/decorations.ts
@@ -1,7 +1,5 @@
import * as vscode from "vscode";
-import { getRightViewColumn, getTestFile } from "./util/vscode";
import * as path from "path";
-import { getLanguageLibrary } from "./languages";
export function showAnswerInTextEditor(
filename: string,
@@ -223,98 +221,3 @@ export function highlightCode(
return key;
}
-
-// Show unit test
-const pythonImportDistinguisher = (line: string): boolean => {
- if (line.startsWith("from") || line.startsWith("import")) {
- return true;
- }
- return false;
-};
-const javascriptImportDistinguisher = (line: string): boolean => {
- if (line.startsWith("import")) {
- return true;
- }
- return false;
-};
-const importDistinguishersMap: {
- [fileExtension: string]: (line: string) => boolean;
-} = {
- js: javascriptImportDistinguisher,
- ts: javascriptImportDistinguisher,
- py: pythonImportDistinguisher,
-};
-function getImportsFromFileString(
- fileString: string,
- importDistinguisher: (line: string) => boolean
-): Set<string> {
- let importLines = new Set<string>();
- for (let line of fileString.split("\n")) {
- if (importDistinguisher(line)) {
- importLines.add(line);
- }
- }
- return importLines;
-}
-function removeRedundantLinesFrom(
- fileContents: string,
- linesToRemove: Set<string>
-): string {
- let fileLines = fileContents.split("\n");
- fileLines = fileLines.filter((line: string) => {
- return !linesToRemove.has(line);
- });
- return fileLines.join("\n");
-}
-
-export async function writeAndShowUnitTest(
- filename: string,
- test: string
-): Promise<DecorationKey> {
- return new Promise((resolve, reject) => {
- let testFilename = getTestFile(filename, true);
- vscode.workspace.openTextDocument(testFilename).then((doc) => {
- let fileContent = doc.getText();
- let fileEmpty = fileContent.trim() === "";
- let existingImportLines = getImportsFromFileString(
- fileContent,
- importDistinguishersMap[doc.fileName.split(".").at(-1) || ".py"]
- );
-
- // Remove redundant imports, make sure pytest is there
- test = removeRedundantLinesFrom(test, existingImportLines);
- test =
- (fileEmpty
- ? `${getLanguageLibrary(".py").writeImport(
- testFilename,
- filename
- )}\nimport pytest\n\n`
- : "\n\n") +
- test.trim() +
- "\n";
-
- vscode.window
- .showTextDocument(doc, getRightViewColumn())
- .then((editor) => {
- let lastLine = editor.document.lineAt(editor.document.lineCount - 1);
- let testRange = new vscode.Range(
- lastLine.range.end,
- new vscode.Position(
- test.split("\n").length + lastLine.range.end.line,
- 0
- )
- );
- editor
- .edit((edit) => {
- edit.insert(lastLine.range.end, test);
- return true;
- })
- .then((success) => {
- if (!success) reject("Failed to insert test");
- let key = highlightCode(editor, testRange);
- resolve(key);
- });
- });
- });
- });
-}
diff --git a/extension/src/extension.ts b/extension/src/extension.ts
index 88af0d19..de8f55e3 100644
--- a/extension/src/extension.ts
+++ b/extension/src/extension.ts
@@ -13,7 +13,7 @@ async function dynamicImportAndActivate(
showTutorial: boolean
) {
const { activateExtension } = await import("./activation/activate");
- activateExtension(context, showTutorial);
+ await activateExtension(context, showTutorial);
}
export function activate(context: vscode.ExtensionContext) {
@@ -25,7 +25,6 @@ export function activate(context: vscode.ExtensionContext) {
cancellable: false,
},
async () => {
- await startContinuePythonServer();
dynamicImportAndActivate(context, true);
}
);
diff --git a/extension/src/lang-server/codeLens.ts b/extension/src/lang-server/codeLens.ts
index 629da0b8..1f352797 100644
--- a/extension/src/lang-server/codeLens.ts
+++ b/extension/src/lang-server/codeLens.ts
@@ -1,5 +1,4 @@
import * as vscode from "vscode";
-import { getLanguageLibrary } from "../languages";
import { editorToSuggestions } from "../suggestions";
class SuggestionsCodeLensProvider implements vscode.CodeLensProvider {
@@ -56,37 +55,6 @@ class SuggestionsCodeLensProvider implements vscode.CodeLensProvider {
}
}
-class PytestCodeLensProvider implements vscode.CodeLensProvider {
- public provideCodeLenses(
- document: vscode.TextDocument,
- token: vscode.CancellationToken
- ): vscode.CodeLens[] | Thenable<vscode.CodeLens[]> {
- const codeLenses: vscode.CodeLens[] = [];
- let lineno = 1;
- const languageLibrary = getLanguageLibrary(document.fileName);
- for (let line of document.getText().split("\n")) {
- if (
- languageLibrary.lineIsFunctionDef(line) &&
- languageLibrary.parseFunctionDefForName(line).startsWith("test_")
- ) {
- const functionToTest = languageLibrary.parseFunctionDefForName(line);
- const fileAndFunctionNameSpecifier =
- document.fileName + "::" + functionToTest;
- codeLenses.push(
- new vscode.CodeLens(new vscode.Range(lineno, 0, lineno, 1), {
- title: "Debug This Test",
- command: "continue.debugTest",
- arguments: [fileAndFunctionNameSpecifier],
- })
- );
- }
- lineno++;
- }
-
- return codeLenses;
- }
-}
-
const allCodeLensProviders: { [langauge: string]: vscode.CodeLensProvider[] } =
{
// python: [new SuggestionsCodeLensProvider(), new PytestCodeLensProvider()],
diff --git a/extension/src/languages/index.d.ts b/extension/src/languages/index.d.ts
deleted file mode 100644
index be7ddfbc..00000000
--- a/extension/src/languages/index.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export interface LanguageLibrary {
- language: string;
- fileExtensions: string[];
- parseFirstStacktrace: (stdout: string) => string | undefined;
- lineIsFunctionDef: (line: string) => boolean;
- parseFunctionDefForName: (line: string) => string;
- lineIsComment: (line: string) => boolean;
- writeImport: (
- sourcePath: string,
- pathToImport: string,
- namesToImport?: string[] | undefined
- ) => string;
-}
diff --git a/extension/src/languages/index.ts b/extension/src/languages/index.ts
deleted file mode 100644
index 31d73a0b..00000000
--- a/extension/src/languages/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import pythonLanguageLibrary from "./python";
-import javascriptLanguageLibrary from "./javascript";
-import { LanguageLibrary } from "./index.d";
-
-export const languageLibraries: LanguageLibrary[] = [
- pythonLanguageLibrary,
- javascriptLanguageLibrary,
-];
-
-export function getLanguageLibrary(filepath: string): LanguageLibrary {
- for (let languageLibrary of languageLibraries) {
- for (let fileExtension of languageLibrary.fileExtensions) {
- if (filepath.endsWith(fileExtension)) {
- return languageLibrary;
- }
- }
- }
- throw new Error(`No language library found for file ${filepath}`);
-}
diff --git a/extension/src/languages/javascript/index.ts b/extension/src/languages/javascript/index.ts
deleted file mode 100644
index 1c21a2fc..00000000
--- a/extension/src/languages/javascript/index.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { LanguageLibrary } from "../index.d";
-import { notImplemented } from "../notImplemented";
-
-const NI = (propertyName: string) => notImplemented(propertyName, "javascript");
-
-const javascriptLangaugeLibrary: LanguageLibrary = {
- language: "javascript",
- fileExtensions: [".js", ".jsx", ".ts", ".tsx"],
- parseFirstStacktrace: NI("parseFirstStacktrace"),
- lineIsFunctionDef: NI("lineIsFunctionDef"),
- parseFunctionDefForName: NI("parseFunctionDefForName"),
- lineIsComment: NI("lineIsComment"),
- writeImport: NI("writeImport"),
-};
-
-export default javascriptLangaugeLibrary;
diff --git a/extension/src/languages/notImplemented.ts b/extension/src/languages/notImplemented.ts
deleted file mode 100644
index bbba2382..00000000
--- a/extension/src/languages/notImplemented.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export function notImplemented(
- propertyName: string,
- langauge: string
-): (...args: any[]) => never {
- return (...args: any[]) => {
- throw new Error(
- `Property ${propertyName} not implemented for language ${langauge}.`
- );
- };
-}
diff --git a/extension/src/languages/python/index.ts b/extension/src/languages/python/index.ts
deleted file mode 100644
index 50282b45..00000000
--- a/extension/src/languages/python/index.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import path = require("path");
-import { LanguageLibrary } from "../index.d";
-
-const tracebackStart = "Traceback (most recent call last):";
-const tracebackEnd = (buf: string): string | undefined => {
- let lines = buf
- .split("\n")
- .filter((line: string) => line.trim() !== "~~^~~")
- .filter((line: string) => line.trim() !== "");
- for (let i = 0; i < lines.length; i++) {
- if (
- lines[i].startsWith(" File") &&
- i + 2 < lines.length &&
- lines[i + 2][0] !== " "
- ) {
- return lines.slice(0, i + 3).join("\n");
- }
- }
- return undefined;
-};
-
-function parseFirstStacktrace(stdout: string): string | undefined {
- let startIdx = stdout.indexOf(tracebackStart);
- if (startIdx < 0) return undefined;
- stdout = stdout.substring(startIdx);
- return tracebackEnd(stdout);
-}
-
-function lineIsFunctionDef(line: string): boolean {
- return line.startsWith("def ");
-}
-
-function parseFunctionDefForName(line: string): string {
- return line.split("def ")[1].split("(")[0];
-}
-
-function lineIsComment(line: string): boolean {
- return line.trim().startsWith("#");
-}
-
-function writeImport(
- sourcePath: string,
- pathToImport: string,
- namesToImport: string[] | undefined = undefined
-): string {
- let segs = path.relative(sourcePath, pathToImport).split(path.sep);
- let importFrom = "";
- for (let seg of segs) {
- if (seg === "..") {
- importFrom = "." + importFrom;
- } else {
- if (!importFrom.endsWith(".")) {
- importFrom += ".";
- }
- importFrom += seg.split(".").slice(0, -1).join(".");
- }
- }
-
- return `from ${importFrom} import ${
- namesToImport ? namesToImport.join(", ") : "*"
- }`;
-}
-
-const pythonLangaugeLibrary: LanguageLibrary = {
- language: "python",
- fileExtensions: [".py"],
- parseFirstStacktrace,
- lineIsFunctionDef,
- parseFunctionDefForName,
- lineIsComment,
- writeImport,
-};
-
-export default pythonLangaugeLibrary;