diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index dfa31a4357f..80f5becb730 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -40,11 +40,13 @@ Cargo.toml
/test/ @jdunkerley @radeusgd @GregoryTravis @AdRiley @marthasharkey
/tools/http-test-helper/ @radeusgd @jdunkerley @GregoryTravis @AdRiley @marthasharkey
-# Dashboard, Cloud & Authentication
+# Dashboard, Cloud, Authentication & Electron
/app/ide-desktop/ @PabloBuchu @indiv0 @somebody1234 @MrFlashAccount
+/app/dashboard/ @PabloBuchu @indiv0 @somebody1234 @MrFlashAccount
# The data-link schema is owned by the libraries team
-/app/ide-desktop/lib/dashboard/src/data/datalinkSchema.json @radeusgd @jdunkerley @GregoryTravis @AdRiley @marthasharkey
-/app/ide-desktop/lib/dashboard/src/data/__tests__ @radeusgd @jdunkerley @GregoryTravis @AdRiley @marthasharkey @PabloBuchu @indiv0 @somebody1234
+/app/dashboard/src/data/datalinkSchema.json @radeusgd @jdunkerley @GregoryTravis @AdRiley @marthasharkey
+/app/dashboard/src/data/__tests__ @radeusgd @jdunkerley @GregoryTravis @AdRiley @marthasharkey @PabloBuchu @indiv0 @somebody1234 @MrFlashAccount
# GUI / Dashboard shared
-/app/ide-desktop/lib/common @PabloBuchu @indiv0 @somebody1234 @MrFlashAccount @Frizi @farmaazon @vitvakatu @kazcw @AdRiley
+/app/*.* @Frizi @farmaazon @vitvakatu @kazcw @AdRiley @PabloBuchu @indiv0 @somebody1234 @MrFlashAccount
+/app/ide-desktop/common @PabloBuchu @indiv0 @somebody1234 @MrFlashAccount @Frizi @farmaazon @vitvakatu @kazcw @AdRiley
diff --git a/app/ide-desktop/.example.env b/app/.example.env
similarity index 100%
rename from app/ide-desktop/.example.env
rename to app/.example.env
diff --git a/app/ide-desktop/.gitignore b/app/.gitignore
similarity index 100%
rename from app/ide-desktop/.gitignore
rename to app/.gitignore
diff --git a/app/ide-desktop/.vscode/react.code-snippets b/app/.vscode/react.code-snippets
similarity index 100%
rename from app/ide-desktop/.vscode/react.code-snippets
rename to app/.vscode/react.code-snippets
diff --git a/app/ide-desktop/.vscode/settings.json b/app/.vscode/settings.json
similarity index 100%
rename from app/ide-desktop/.vscode/settings.json
rename to app/.vscode/settings.json
diff --git a/app/ide-desktop/README.md b/app/README.md
similarity index 85%
rename from app/ide-desktop/README.md
rename to app/README.md
index d6018e582aa..39fa4f44c78 100644
--- a/app/ide-desktop/README.md
+++ b/app/README.md
@@ -17,9 +17,6 @@ internal folder structure of the module.
- [`dashboard/`](./lib/dashboard/README.md): The dashboard, used to manage
projects. It launches the GUI (located in `content/` for GUI1, or `/app/gui2/`
for GUI2) when a project is opened.
-- `esbuild-plugin-copy-directories/`: An ESBuild plugin for continuously copying
- directories from the a given location to a given subdirectory of the build
- output directory.
- `icons/`: Generates the logo for the app.
- `ts-plugin-namespace-auto-import/`: (WIP) A TypeScript plugin to change
auto-import to use `import * as moduleName` rather than `import {}`.
diff --git a/app/ide-desktop/lib/dashboard/.gitignore b/app/dashboard/.gitignore
similarity index 71%
rename from app/ide-desktop/lib/dashboard/.gitignore
rename to app/dashboard/.gitignore
index 75e854d8dcf..9783bc3d0fd 100644
--- a/app/ide-desktop/lib/dashboard/.gitignore
+++ b/app/dashboard/.gitignore
@@ -2,3 +2,4 @@ node_modules/
/test-results/
/playwright-report/
/playwright/.cache/
+!/src/assets/background.jpg
diff --git a/app/ide-desktop/lib/dashboard/.prettierignore b/app/dashboard/.prettierignore
similarity index 100%
rename from app/ide-desktop/lib/dashboard/.prettierignore
rename to app/dashboard/.prettierignore
diff --git a/app/ide-desktop/lib/dashboard/.prettierrc.cjs b/app/dashboard/.prettierrc.cjs
similarity index 97%
rename from app/ide-desktop/lib/dashboard/.prettierrc.cjs
rename to app/dashboard/.prettierrc.cjs
index c77f185acd6..871da65004c 100644
--- a/app/ide-desktop/lib/dashboard/.prettierrc.cjs
+++ b/app/dashboard/.prettierrc.cjs
@@ -22,6 +22,8 @@ module.exports = {
'',
'^enso-',
'',
+ '^#[/]assets',
+ '',
'^#[/]App',
'^#[/]appUtils',
'^#[/]text',
diff --git a/app/ide-desktop/lib/dashboard/404.html b/app/dashboard/404.html
similarity index 100%
rename from app/ide-desktop/lib/dashboard/404.html
rename to app/dashboard/404.html
diff --git a/app/ide-desktop/lib/dashboard/README.md b/app/dashboard/README.md
similarity index 100%
rename from app/ide-desktop/lib/dashboard/README.md
rename to app/dashboard/README.md
diff --git a/app/ide-desktop/lib/dashboard/docs/browser_specific_behavior.md b/app/dashboard/docs/browser_specific_behavior.md
similarity index 100%
rename from app/ide-desktop/lib/dashboard/docs/browser_specific_behavior.md
rename to app/dashboard/docs/browser_specific_behavior.md
diff --git a/app/ide-desktop/lib/dashboard/e2e/README.md b/app/dashboard/e2e/README.md
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/README.md
rename to app/dashboard/e2e/README.md
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions.ts b/app/dashboard/e2e/actions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions.ts
rename to app/dashboard/e2e/actions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/BaseActions.ts b/app/dashboard/e2e/actions/BaseActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/BaseActions.ts
rename to app/dashboard/e2e/actions/BaseActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/DrivePageActions.ts b/app/dashboard/e2e/actions/DrivePageActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/DrivePageActions.ts
rename to app/dashboard/e2e/actions/DrivePageActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/EditorPageActions.ts b/app/dashboard/e2e/actions/EditorPageActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/EditorPageActions.ts
rename to app/dashboard/e2e/actions/EditorPageActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/LoginPageActions.ts b/app/dashboard/e2e/actions/LoginPageActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/LoginPageActions.ts
rename to app/dashboard/e2e/actions/LoginPageActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/NewDataLinkModalActions.ts b/app/dashboard/e2e/actions/NewDataLinkModalActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/NewDataLinkModalActions.ts
rename to app/dashboard/e2e/actions/NewDataLinkModalActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/PageActions.ts b/app/dashboard/e2e/actions/PageActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/PageActions.ts
rename to app/dashboard/e2e/actions/PageActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/SetUsernamePageActions.ts b/app/dashboard/e2e/actions/SetUsernamePageActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/SetUsernamePageActions.ts
rename to app/dashboard/e2e/actions/SetUsernamePageActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/SettingsPageActions.ts b/app/dashboard/e2e/actions/SettingsPageActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/SettingsPageActions.ts
rename to app/dashboard/e2e/actions/SettingsPageActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/StartModalActions.ts b/app/dashboard/e2e/actions/StartModalActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/StartModalActions.ts
rename to app/dashboard/e2e/actions/StartModalActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/contextMenuActions.ts b/app/dashboard/e2e/actions/contextMenuActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/contextMenuActions.ts
rename to app/dashboard/e2e/actions/contextMenuActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/goToPageActions.ts b/app/dashboard/e2e/actions/goToPageActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/goToPageActions.ts
rename to app/dashboard/e2e/actions/goToPageActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/openUserMenuAction.ts b/app/dashboard/e2e/actions/openUserMenuAction.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/openUserMenuAction.ts
rename to app/dashboard/e2e/actions/openUserMenuAction.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/actions/userMenuActions.ts b/app/dashboard/e2e/actions/userMenuActions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/actions/userMenuActions.ts
rename to app/dashboard/e2e/actions/userMenuActions.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/api.ts b/app/dashboard/e2e/api.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/api.ts
rename to app/dashboard/e2e/api.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/assetPanel.spec.ts b/app/dashboard/e2e/assetPanel.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/assetPanel.spec.ts
rename to app/dashboard/e2e/assetPanel.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/assetSearchBar.spec.ts b/app/dashboard/e2e/assetSearchBar.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/assetSearchBar.spec.ts
rename to app/dashboard/e2e/assetSearchBar.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/assetsTableFeatures.spec.ts b/app/dashboard/e2e/assetsTableFeatures.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/assetsTableFeatures.spec.ts
rename to app/dashboard/e2e/assetsTableFeatures.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/copy.spec.ts b/app/dashboard/e2e/copy.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/copy.spec.ts
rename to app/dashboard/e2e/copy.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/createAsset.spec.ts b/app/dashboard/e2e/createAsset.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/createAsset.spec.ts
rename to app/dashboard/e2e/createAsset.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/dataLinkEditor.spec.ts b/app/dashboard/e2e/dataLinkEditor.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/dataLinkEditor.spec.ts
rename to app/dashboard/e2e/dataLinkEditor.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/delete.spec.ts b/app/dashboard/e2e/delete.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/delete.spec.ts
rename to app/dashboard/e2e/delete.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/driveView.spec.ts b/app/dashboard/e2e/driveView.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/driveView.spec.ts
rename to app/dashboard/e2e/driveView.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/editAssetName.spec.ts b/app/dashboard/e2e/editAssetName.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/editAssetName.spec.ts
rename to app/dashboard/e2e/editAssetName.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/labels.spec.ts b/app/dashboard/e2e/labels.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/labels.spec.ts
rename to app/dashboard/e2e/labels.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/labelsPanel.spec.ts b/app/dashboard/e2e/labelsPanel.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/labelsPanel.spec.ts
rename to app/dashboard/e2e/labelsPanel.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/loginLogout.spec.ts b/app/dashboard/e2e/loginLogout.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/loginLogout.spec.ts
rename to app/dashboard/e2e/loginLogout.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/loginScreen.spec.ts b/app/dashboard/e2e/loginScreen.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/loginScreen.spec.ts
rename to app/dashboard/e2e/loginScreen.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/membersSettings.spec.ts b/app/dashboard/e2e/membersSettings.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/membersSettings.spec.ts
rename to app/dashboard/e2e/membersSettings.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/organizationSettings.spec.ts b/app/dashboard/e2e/organizationSettings.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/organizationSettings.spec.ts
rename to app/dashboard/e2e/organizationSettings.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/pageSwitcher.spec.ts b/app/dashboard/e2e/pageSwitcher.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/pageSwitcher.spec.ts
rename to app/dashboard/e2e/pageSwitcher.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/signUp.spec.ts b/app/dashboard/e2e/signUp.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/signUp.spec.ts
rename to app/dashboard/e2e/signUp.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/sort.spec.ts b/app/dashboard/e2e/sort.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/sort.spec.ts
rename to app/dashboard/e2e/sort.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/startModal.spec.ts b/app/dashboard/e2e/startModal.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/startModal.spec.ts
rename to app/dashboard/e2e/startModal.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/userMenu.spec.ts b/app/dashboard/e2e/userMenu.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/userMenu.spec.ts
rename to app/dashboard/e2e/userMenu.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/e2e/userSettings.spec.ts b/app/dashboard/e2e/userSettings.spec.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/e2e/userSettings.spec.ts
rename to app/dashboard/e2e/userSettings.spec.ts
diff --git a/app/ide-desktop/lib/dashboard/favicon.ico b/app/dashboard/favicon.ico
similarity index 100%
rename from app/ide-desktop/lib/dashboard/favicon.ico
rename to app/dashboard/favicon.ico
diff --git a/app/ide-desktop/lib/dashboard/index.html b/app/dashboard/index.html
similarity index 100%
rename from app/ide-desktop/lib/dashboard/index.html
rename to app/dashboard/index.html
diff --git a/app/ide-desktop/lib/dashboard/package.json b/app/dashboard/package.json
similarity index 88%
rename from app/ide-desktop/lib/dashboard/package.json
rename to app/dashboard/package.json
index 54f70539320..8a67541739c 100644
--- a/app/ide-desktop/lib/dashboard/package.json
+++ b/app/dashboard/package.json
@@ -32,11 +32,12 @@
"@hookform/resolvers": "^3.4.0",
"@monaco-editor/react": "4.6.0",
"@sentry/react": "^7.74.0",
+ "@stripe/react-stripe-js": "^2.7.1",
+ "@stripe/stripe-js": "^3.5.0",
"@tanstack/react-query": "5.45.1",
"@tanstack/vue-query": ">= 5.45.0 < 5.46.0",
"ajv": "^8.12.0",
"clsx": "^2.1.1",
- "enso-assets": "workspace:*",
"enso-common": "workspace:*",
"is-network-error": "^1.0.1",
"monaco-editor": "0.48.0",
@@ -59,14 +60,13 @@
"zustand": "^4.5.4"
},
"devDependencies": {
- "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
"@fast-check/vitest": "^0.0.8",
"@ianvs/prettier-plugin-sort-imports": "^4.1.1",
"@modyfi/vite-plugin-yaml": "^1.0.4",
- "@playwright/experimental-ct-react": "^1.40.0",
"@playwright/test": "^1.40.0",
"@react-types/shared": "^3.22.1",
"@tanstack/react-query-devtools": "5.45.1",
+ "@types/eslint__js": "^8.42.3",
"@types/node": "^20.11.21",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
@@ -77,12 +77,7 @@
"chalk": "^5.3.0",
"cross-env": "^7.0.3",
"enso-chat": "git://github.com/enso-org/enso-bot",
- "esbuild": "^0.19.3",
- "esbuild-plugin-inline-image": "^0.0.9",
- "esbuild-plugin-time": "^1.0.0",
- "esbuild-plugin-yaml": "^0.0.1",
"eslint": "^8.49.0",
- "eslint-plugin-jsdoc": "^46.8.1",
"eslint-plugin-react": "^7.32.1",
"fast-check": "^3.15.0",
"playwright": "^1.38.0",
@@ -92,7 +87,6 @@
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "1.0.7",
"tailwindcss-react-aria-components": "^1.1.1",
- "ts-plugin-namespace-auto-import": "workspace:*",
"typescript": "^5.5.3",
"vite": "^5.3.3",
"vitest": "^1.3.1"
diff --git a/app/ide-desktop/lib/dashboard/playwright.config.ts b/app/dashboard/playwright.config.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/playwright.config.ts
rename to app/dashboard/playwright.config.ts
diff --git a/app/ide-desktop/lib/dashboard/postcss.config.js b/app/dashboard/postcss.config.js
similarity index 100%
rename from app/ide-desktop/lib/dashboard/postcss.config.js
rename to app/dashboard/postcss.config.js
diff --git a/app/ide-desktop/lib/dashboard/src/App.tsx b/app/dashboard/src/App.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/App.tsx
rename to app/dashboard/src/App.tsx
index 0be8c884b12..bd96d2feec8 100644
--- a/app/ide-desktop/lib/dashboard/src/App.tsx
+++ b/app/dashboard/src/App.tsx
@@ -40,7 +40,6 @@ import * as router from 'react-router-dom'
import * as toastify from 'react-toastify'
import * as detect from 'enso-common/src/detect'
-import type * as types from 'enso-common/src/types'
import * as appUtils from '#/appUtils'
@@ -71,6 +70,7 @@ import Dashboard from '#/pages/dashboard/Dashboard'
import * as subscribe from '#/pages/subscribe/Subscribe'
import * as subscribeSuccess from '#/pages/subscribe/SubscribeSuccess'
+import type * as editor from '#/layouts/Editor'
import * as openAppWatcher from '#/layouts/OpenAppWatcher'
import * as devtools from '#/components/Devtools'
@@ -154,7 +154,7 @@ export interface AppProps {
readonly onAuthenticated: (accessToken: string | null) => void
readonly projectManagerUrl: string | null
readonly ydocUrl: string | null
- readonly appRunner: types.EditorRunner | null
+ readonly appRunner: editor.GraphEditorRunner | null
readonly portalRoot: Element
readonly httpClient: HttpClient
readonly queryClient: reactQuery.QueryClient
diff --git a/app/ide-desktop/lib/dashboard/src/TestAppRunner.tsx b/app/dashboard/src/TestAppRunner.tsx
similarity index 70%
rename from app/ide-desktop/lib/dashboard/src/TestAppRunner.tsx
rename to app/dashboard/src/TestAppRunner.tsx
index 1743d43de4f..a01636e62ba 100644
--- a/app/ide-desktop/lib/dashboard/src/TestAppRunner.tsx
+++ b/app/dashboard/src/TestAppRunner.tsx
@@ -1,9 +1,8 @@
/** @file Placeholder component for GUI used during e2e tests. */
-
-import type * as types from 'enso-common/src/types'
+import type * as editor from '#/layouts/Editor'
/** Placeholder component for GUI used during e2e tests. */
-export function TestAppRunner(props: types.EditorProps) {
+export function TestAppRunner(props: editor.GraphEditorProps) {
// eslint-disable-next-line no-restricted-syntax
return props.hidden ? <>> :
Vue app loads here.
}
diff --git a/app/ide-desktop/lib/dashboard/src/appUtils.tsx b/app/dashboard/src/appUtils.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/appUtils.tsx
rename to app/dashboard/src/appUtils.tsx
diff --git a/app/ide-desktop/lib/assets/accessed_by_projects.svg b/app/dashboard/src/assets/accessed_by_projects.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/accessed_by_projects.svg
rename to app/dashboard/src/assets/accessed_by_projects.svg
diff --git a/app/ide-desktop/lib/assets/accessed_data.svg b/app/dashboard/src/assets/accessed_data.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/accessed_data.svg
rename to app/dashboard/src/assets/accessed_data.svg
diff --git a/app/ide-desktop/lib/assets/add_datalink.svg b/app/dashboard/src/assets/add_datalink.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/add_datalink.svg
rename to app/dashboard/src/assets/add_datalink.svg
diff --git a/app/ide-desktop/lib/assets/add_folder.svg b/app/dashboard/src/assets/add_folder.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/add_folder.svg
rename to app/dashboard/src/assets/add_folder.svg
diff --git a/app/ide-desktop/lib/assets/add_key.svg b/app/dashboard/src/assets/add_key.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/add_key.svg
rename to app/dashboard/src/assets/add_key.svg
diff --git a/app/ide-desktop/lib/assets/add_network.svg b/app/dashboard/src/assets/add_network.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/add_network.svg
rename to app/dashboard/src/assets/add_network.svg
diff --git a/app/ide-desktop/lib/assets/app_download.svg b/app/dashboard/src/assets/app_download.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/app_download.svg
rename to app/dashboard/src/assets/app_download.svg
diff --git a/app/ide-desktop/lib/assets/arrow_left.svg b/app/dashboard/src/assets/arrow_left.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/arrow_left.svg
rename to app/dashboard/src/assets/arrow_left.svg
diff --git a/app/ide-desktop/lib/assets/arrow_right.svg b/app/dashboard/src/assets/arrow_right.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/arrow_right.svg
rename to app/dashboard/src/assets/arrow_right.svg
diff --git a/app/ide-desktop/lib/assets/arrow_up.svg b/app/dashboard/src/assets/arrow_up.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/arrow_up.svg
rename to app/dashboard/src/assets/arrow_up.svg
diff --git a/app/ide-desktop/lib/assets/at.svg b/app/dashboard/src/assets/at.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/at.svg
rename to app/dashboard/src/assets/at.svg
diff --git a/app/ide-desktop/lib/assets/background.jpg b/app/dashboard/src/assets/background.jpg
similarity index 100%
rename from app/ide-desktop/lib/assets/background.jpg
rename to app/dashboard/src/assets/background.jpg
diff --git a/app/ide-desktop/lib/assets/bell.svg b/app/dashboard/src/assets/bell.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/bell.svg
rename to app/dashboard/src/assets/bell.svg
diff --git a/app/ide-desktop/lib/assets/blank.svg b/app/dashboard/src/assets/blank.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/blank.svg
rename to app/dashboard/src/assets/blank.svg
diff --git a/app/ide-desktop/lib/assets/blank_16.svg b/app/dashboard/src/assets/blank_16.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/blank_16.svg
rename to app/dashboard/src/assets/blank_16.svg
diff --git a/app/ide-desktop/lib/assets/breadcrumb_arrow.svg b/app/dashboard/src/assets/breadcrumb_arrow.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/breadcrumb_arrow.svg
rename to app/dashboard/src/assets/breadcrumb_arrow.svg
diff --git a/app/ide-desktop/lib/assets/burger_menu.svg b/app/dashboard/src/assets/burger_menu.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/burger_menu.svg
rename to app/dashboard/src/assets/burger_menu.svg
diff --git a/app/ide-desktop/lib/assets/camera.svg b/app/dashboard/src/assets/camera.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/camera.svg
rename to app/dashboard/src/assets/camera.svg
diff --git a/app/ide-desktop/lib/assets/chat.svg b/app/dashboard/src/assets/chat.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/chat.svg
rename to app/dashboard/src/assets/chat.svg
diff --git a/app/ide-desktop/lib/assets/check_mark.svg b/app/dashboard/src/assets/check_mark.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/check_mark.svg
rename to app/dashboard/src/assets/check_mark.svg
diff --git a/app/ide-desktop/lib/assets/close.svg b/app/dashboard/src/assets/close.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/close.svg
rename to app/dashboard/src/assets/close.svg
diff --git a/app/ide-desktop/lib/assets/close_large.svg b/app/dashboard/src/assets/close_large.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/close_large.svg
rename to app/dashboard/src/assets/close_large.svg
diff --git a/app/ide-desktop/lib/assets/cloud.svg b/app/dashboard/src/assets/cloud.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/cloud.svg
rename to app/dashboard/src/assets/cloud.svg
diff --git a/app/ide-desktop/lib/assets/cloud_to.svg b/app/dashboard/src/assets/cloud_to.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/cloud_to.svg
rename to app/dashboard/src/assets/cloud_to.svg
diff --git a/app/ide-desktop/lib/assets/command_key.svg b/app/dashboard/src/assets/command_key.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/command_key.svg
rename to app/dashboard/src/assets/command_key.svg
diff --git a/app/ide-desktop/lib/assets/compare.svg b/app/dashboard/src/assets/compare.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/compare.svg
rename to app/dashboard/src/assets/compare.svg
diff --git a/app/ide-desktop/lib/assets/computer.svg b/app/dashboard/src/assets/computer.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/computer.svg
rename to app/dashboard/src/assets/computer.svg
diff --git a/app/ide-desktop/lib/assets/copy.svg b/app/dashboard/src/assets/copy.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/copy.svg
rename to app/dashboard/src/assets/copy.svg
diff --git a/app/ide-desktop/lib/assets/copy_as_path.svg b/app/dashboard/src/assets/copy_as_path.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/copy_as_path.svg
rename to app/dashboard/src/assets/copy_as_path.svg
diff --git a/app/ide-desktop/lib/assets/create_account.svg b/app/dashboard/src/assets/create_account.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/create_account.svg
rename to app/dashboard/src/assets/create_account.svg
diff --git a/app/ide-desktop/lib/assets/cross.svg b/app/dashboard/src/assets/cross.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/cross.svg
rename to app/dashboard/src/assets/cross.svg
diff --git a/app/ide-desktop/lib/assets/cross2.svg b/app/dashboard/src/assets/cross2.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/cross2.svg
rename to app/dashboard/src/assets/cross2.svg
diff --git a/app/ide-desktop/lib/assets/ctrl_key.svg b/app/dashboard/src/assets/ctrl_key.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/ctrl_key.svg
rename to app/dashboard/src/assets/ctrl_key.svg
diff --git a/app/ide-desktop/lib/assets/data_download.svg b/app/dashboard/src/assets/data_download.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/data_download.svg
rename to app/dashboard/src/assets/data_download.svg
diff --git a/app/ide-desktop/lib/assets/data_upload.svg b/app/dashboard/src/assets/data_upload.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/data_upload.svg
rename to app/dashboard/src/assets/data_upload.svg
diff --git a/app/ide-desktop/lib/assets/datalink.svg b/app/dashboard/src/assets/datalink.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/datalink.svg
rename to app/dashboard/src/assets/datalink.svg
diff --git a/app/ide-desktop/lib/assets/default_user.svg b/app/dashboard/src/assets/default_user.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/default_user.svg
rename to app/dashboard/src/assets/default_user.svg
diff --git a/app/ide-desktop/lib/assets/discord.svg b/app/dashboard/src/assets/discord.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/discord.svg
rename to app/dashboard/src/assets/discord.svg
diff --git a/app/ide-desktop/lib/assets/dismiss.svg b/app/dashboard/src/assets/dismiss.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/dismiss.svg
rename to app/dashboard/src/assets/dismiss.svg
diff --git a/app/ide-desktop/lib/assets/docs.svg b/app/dashboard/src/assets/docs.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/docs.svg
rename to app/dashboard/src/assets/docs.svg
diff --git a/app/ide-desktop/lib/assets/drive.svg b/app/dashboard/src/assets/drive.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/drive.svg
rename to app/dashboard/src/assets/drive.svg
diff --git a/app/ide-desktop/lib/assets/drop_files.svg b/app/dashboard/src/assets/drop_files.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/drop_files.svg
rename to app/dashboard/src/assets/drop_files.svg
diff --git a/app/ide-desktop/lib/assets/duplicate.svg b/app/dashboard/src/assets/duplicate.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/duplicate.svg
rename to app/dashboard/src/assets/duplicate.svg
diff --git a/app/ide-desktop/lib/assets/enso_logo.svg b/app/dashboard/src/assets/enso_logo.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/enso_logo.svg
rename to app/dashboard/src/assets/enso_logo.svg
diff --git a/app/ide-desktop/lib/assets/eye.svg b/app/dashboard/src/assets/eye.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/eye.svg
rename to app/dashboard/src/assets/eye.svg
diff --git a/app/ide-desktop/lib/assets/eye_crossed.svg b/app/dashboard/src/assets/eye_crossed.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/eye_crossed.svg
rename to app/dashboard/src/assets/eye_crossed.svg
diff --git a/app/ide-desktop/lib/assets/find.svg b/app/dashboard/src/assets/find.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/find.svg
rename to app/dashboard/src/assets/find.svg
diff --git a/app/ide-desktop/lib/assets/folder.svg b/app/dashboard/src/assets/folder.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/folder.svg
rename to app/dashboard/src/assets/folder.svg
diff --git a/app/ide-desktop/lib/assets/folder_arrow.svg b/app/dashboard/src/assets/folder_arrow.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/folder_arrow.svg
rename to app/dashboard/src/assets/folder_arrow.svg
diff --git a/app/ide-desktop/lib/assets/folder_arrow_double.svg b/app/dashboard/src/assets/folder_arrow_double.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/folder_arrow_double.svg
rename to app/dashboard/src/assets/folder_arrow_double.svg
diff --git a/app/ide-desktop/lib/assets/geo.svg b/app/dashboard/src/assets/geo.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/geo.svg
rename to app/dashboard/src/assets/geo.svg
diff --git a/app/ide-desktop/lib/assets/github.svg b/app/dashboard/src/assets/github.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/github.svg
rename to app/dashboard/src/assets/github.svg
diff --git a/app/ide-desktop/lib/assets/go_back.svg b/app/dashboard/src/assets/go_back.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/go_back.svg
rename to app/dashboard/src/assets/go_back.svg
diff --git a/app/ide-desktop/lib/assets/google.svg b/app/dashboard/src/assets/google.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/google.svg
rename to app/dashboard/src/assets/google.svg
diff --git a/app/ide-desktop/lib/assets/heart.svg b/app/dashboard/src/assets/heart.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/heart.svg
rename to app/dashboard/src/assets/heart.svg
diff --git a/app/ide-desktop/lib/assets/integrations.png b/app/dashboard/src/assets/integrations.png
similarity index 100%
rename from app/ide-desktop/lib/assets/integrations.png
rename to app/dashboard/src/assets/integrations.png
diff --git a/app/ide-desktop/lib/assets/key.svg b/app/dashboard/src/assets/key.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/key.svg
rename to app/dashboard/src/assets/key.svg
diff --git a/app/ide-desktop/lib/assets/keyboard_shortcuts.svg b/app/dashboard/src/assets/keyboard_shortcuts.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/keyboard_shortcuts.svg
rename to app/dashboard/src/assets/keyboard_shortcuts.svg
diff --git a/app/ide-desktop/lib/assets/lock.svg b/app/dashboard/src/assets/lock.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/lock.svg
rename to app/dashboard/src/assets/lock.svg
diff --git a/app/ide-desktop/lib/assets/log.svg b/app/dashboard/src/assets/log.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/log.svg
rename to app/dashboard/src/assets/log.svg
diff --git a/app/ide-desktop/lib/assets/logs.svg b/app/dashboard/src/assets/logs.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/logs.svg
rename to app/dashboard/src/assets/logs.svg
diff --git a/app/ide-desktop/lib/assets/network.svg b/app/dashboard/src/assets/network.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/network.svg
rename to app/dashboard/src/assets/network.svg
diff --git a/app/ide-desktop/lib/assets/open.svg b/app/dashboard/src/assets/open.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/open.svg
rename to app/dashboard/src/assets/open.svg
diff --git a/app/ide-desktop/lib/assets/open_count.svg b/app/dashboard/src/assets/open_count.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/open_count.svg
rename to app/dashboard/src/assets/open_count.svg
diff --git a/app/ide-desktop/lib/assets/open_in_file_browser.svg b/app/dashboard/src/assets/open_in_file_browser.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/open_in_file_browser.svg
rename to app/dashboard/src/assets/open_in_file_browser.svg
diff --git a/app/ide-desktop/lib/assets/option_key.svg b/app/dashboard/src/assets/option_key.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/option_key.svg
rename to app/dashboard/src/assets/option_key.svg
diff --git a/app/ide-desktop/lib/assets/paste.svg b/app/dashboard/src/assets/paste.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/paste.svg
rename to app/dashboard/src/assets/paste.svg
diff --git a/app/ide-desktop/lib/assets/pen.svg b/app/dashboard/src/assets/pen.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/pen.svg
rename to app/dashboard/src/assets/pen.svg
diff --git a/app/ide-desktop/lib/assets/people.svg b/app/dashboard/src/assets/people.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/people.svg
rename to app/dashboard/src/assets/people.svg
diff --git a/app/ide-desktop/lib/assets/people_settings.svg b/app/dashboard/src/assets/people_settings.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/people_settings.svg
rename to app/dashboard/src/assets/people_settings.svg
diff --git a/app/ide-desktop/lib/assets/play.svg b/app/dashboard/src/assets/play.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/play.svg
rename to app/dashboard/src/assets/play.svg
diff --git a/app/ide-desktop/lib/assets/play2.svg b/app/dashboard/src/assets/play2.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/play2.svg
rename to app/dashboard/src/assets/play2.svg
diff --git a/app/ide-desktop/lib/assets/plus.svg b/app/dashboard/src/assets/plus.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/plus.svg
rename to app/dashboard/src/assets/plus.svg
diff --git a/app/ide-desktop/lib/assets/plus2.svg b/app/dashboard/src/assets/plus2.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/plus2.svg
rename to app/dashboard/src/assets/plus2.svg
diff --git a/app/ide-desktop/lib/assets/project_icon.svg b/app/dashboard/src/assets/project_icon.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/project_icon.svg
rename to app/dashboard/src/assets/project_icon.svg
diff --git a/app/ide-desktop/lib/assets/recent.svg b/app/dashboard/src/assets/recent.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/recent.svg
rename to app/dashboard/src/assets/recent.svg
diff --git a/app/ide-desktop/lib/assets/reload.svg b/app/dashboard/src/assets/reload.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/reload.svg
rename to app/dashboard/src/assets/reload.svg
diff --git a/app/ide-desktop/lib/assets/restore.svg b/app/dashboard/src/assets/restore.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/restore.svg
rename to app/dashboard/src/assets/restore.svg
diff --git a/app/ide-desktop/lib/assets/right_panel.svg b/app/dashboard/src/assets/right_panel.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/right_panel.svg
rename to app/dashboard/src/assets/right_panel.svg
diff --git a/app/ide-desktop/lib/assets/root.svg b/app/dashboard/src/assets/root.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/root.svg
rename to app/dashboard/src/assets/root.svg
diff --git a/app/ide-desktop/lib/assets/scissors.svg b/app/dashboard/src/assets/scissors.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/scissors.svg
rename to app/dashboard/src/assets/scissors.svg
diff --git a/app/ide-desktop/lib/assets/settings.svg b/app/dashboard/src/assets/settings.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/settings.svg
rename to app/dashboard/src/assets/settings.svg
diff --git a/app/ide-desktop/lib/assets/shift_key.svg b/app/dashboard/src/assets/shift_key.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/shift_key.svg
rename to app/dashboard/src/assets/shift_key.svg
diff --git a/app/ide-desktop/lib/assets/sign_in.svg b/app/dashboard/src/assets/sign_in.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/sign_in.svg
rename to app/dashboard/src/assets/sign_in.svg
diff --git a/app/ide-desktop/lib/assets/sign_out.svg b/app/dashboard/src/assets/sign_out.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/sign_out.svg
rename to app/dashboard/src/assets/sign_out.svg
diff --git a/app/ide-desktop/lib/assets/sliders.svg b/app/dashboard/src/assets/sliders.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/sliders.svg
rename to app/dashboard/src/assets/sliders.svg
diff --git a/app/ide-desktop/lib/assets/sort_ascending.svg b/app/dashboard/src/assets/sort_ascending.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/sort_ascending.svg
rename to app/dashboard/src/assets/sort_ascending.svg
diff --git a/app/ide-desktop/lib/assets/spreadsheets.svg b/app/dashboard/src/assets/spreadsheets.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/spreadsheets.svg
rename to app/dashboard/src/assets/spreadsheets.svg
diff --git a/app/ide-desktop/lib/assets/stop.svg b/app/dashboard/src/assets/stop.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/stop.svg
rename to app/dashboard/src/assets/stop.svg
diff --git a/app/ide-desktop/lib/assets/tag.svg b/app/dashboard/src/assets/tag.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/tag.svg
rename to app/dashboard/src/assets/tag.svg
diff --git a/app/ide-desktop/lib/assets/temp.svg b/app/dashboard/src/assets/temp.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/temp.svg
rename to app/dashboard/src/assets/temp.svg
diff --git a/app/ide-desktop/lib/assets/text.svg b/app/dashboard/src/assets/text.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/text.svg
rename to app/dashboard/src/assets/text.svg
diff --git a/app/ide-desktop/lib/assets/tick.svg b/app/dashboard/src/assets/tick.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/tick.svg
rename to app/dashboard/src/assets/tick.svg
diff --git a/app/ide-desktop/lib/assets/time.svg b/app/dashboard/src/assets/time.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/time.svg
rename to app/dashboard/src/assets/time.svg
diff --git a/app/ide-desktop/lib/assets/trash.svg b/app/dashboard/src/assets/trash.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/trash.svg
rename to app/dashboard/src/assets/trash.svg
diff --git a/app/ide-desktop/lib/assets/trash2.svg b/app/dashboard/src/assets/trash2.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/trash2.svg
rename to app/dashboard/src/assets/trash2.svg
diff --git a/app/ide-desktop/lib/assets/triangle_down.svg b/app/dashboard/src/assets/triangle_down.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/triangle_down.svg
rename to app/dashboard/src/assets/triangle_down.svg
diff --git a/app/ide-desktop/lib/assets/untrash.svg b/app/dashboard/src/assets/untrash.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/untrash.svg
rename to app/dashboard/src/assets/untrash.svg
diff --git a/app/ide-desktop/lib/assets/visualize.png b/app/dashboard/src/assets/visualize.png
similarity index 100%
rename from app/ide-desktop/lib/assets/visualize.png
rename to app/dashboard/src/assets/visualize.png
diff --git a/app/ide-desktop/lib/assets/windows_key.svg b/app/dashboard/src/assets/windows_key.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/windows_key.svg
rename to app/dashboard/src/assets/windows_key.svg
diff --git a/app/ide-desktop/lib/assets/workspace.svg b/app/dashboard/src/assets/workspace.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/workspace.svg
rename to app/dashboard/src/assets/workspace.svg
diff --git a/app/ide-desktop/lib/assets/youtube.svg b/app/dashboard/src/assets/youtube.svg
similarity index 100%
rename from app/ide-desktop/lib/assets/youtube.svg
rename to app/dashboard/src/assets/youtube.svg
diff --git a/app/ide-desktop/lib/dashboard/src/authentication/cognito.mock.ts b/app/dashboard/src/authentication/cognito.mock.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/authentication/cognito.mock.ts
rename to app/dashboard/src/authentication/cognito.mock.ts
diff --git a/app/ide-desktop/lib/dashboard/src/authentication/cognito.ts b/app/dashboard/src/authentication/cognito.ts
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/authentication/cognito.ts
rename to app/dashboard/src/authentication/cognito.ts
index d0c5c1002e1..cbc2e2a83c9 100644
--- a/app/ide-desktop/lib/dashboard/src/authentication/cognito.ts
+++ b/app/dashboard/src/authentication/cognito.ts
@@ -37,6 +37,7 @@ import * as detect from 'enso-common/src/detect'
import type * as loggerProvider from '#/providers/LoggerProvider'
+import type * as saveAccessToken from '#/utilities/accessToken'
import * as dateTime from '#/utilities/dateTime'
import * as service from '#/authentication/service'
@@ -188,7 +189,7 @@ export class Cognito {
}
/** Save the access token to a file for further reuse. */
- saveAccessToken(accessTokenPayload: SaveAccessTokenPayload | null) {
+ saveAccessToken(accessTokenPayload: saveAccessToken.AccessToken | null) {
this.amplifyConfig.saveAccessToken?.(accessTokenPayload)
}
diff --git a/app/ide-desktop/lib/dashboard/src/authentication/listen.mock.ts b/app/dashboard/src/authentication/listen.mock.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/authentication/listen.mock.ts
rename to app/dashboard/src/authentication/listen.mock.ts
diff --git a/app/ide-desktop/lib/dashboard/src/authentication/listen.ts b/app/dashboard/src/authentication/listen.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/authentication/listen.ts
rename to app/dashboard/src/authentication/listen.ts
diff --git a/app/ide-desktop/lib/dashboard/src/authentication/service.ts b/app/dashboard/src/authentication/service.ts
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/authentication/service.ts
rename to app/dashboard/src/authentication/service.ts
index 930a566a50f..ad5d2d8dc7e 100644
--- a/app/ide-desktop/lib/dashboard/src/authentication/service.ts
+++ b/app/dashboard/src/authentication/service.ts
@@ -10,6 +10,8 @@ import * as appUtils from '#/appUtils'
import type * as loggerProvider from '#/providers/LoggerProvider'
+import type * as saveAccessTokenModule from '#/utilities/accessToken'
+
import * as cognitoModule from '#/authentication/cognito'
import * as listen from '#/authentication/listen'
@@ -27,7 +29,7 @@ export interface AmplifyConfig {
readonly userPoolId: string
readonly userPoolWebClientId: string
readonly urlOpener: ((url: string, redirectUrl: string) => void) | null
- readonly saveAccessToken: ((accessToken: SaveAccessTokenPayload | null) => void) | null
+ readonly saveAccessToken: ((accessToken: saveAccessTokenModule.AccessToken | null) => void) | null
readonly domain: string
readonly scope: string[]
readonly redirectSignIn: string
@@ -138,14 +140,15 @@ function loadAmplifyConfig(
navigate: (url: string) => void
): AmplifyConfig | null {
let urlOpener: ((url: string) => void) | null = null
- let saveAccessToken: ((accessToken: SaveAccessTokenPayload | null) => void) | null = null
+ let saveAccessToken: ((accessToken: saveAccessTokenModule.AccessToken | null) => void) | null =
+ null
if ('authenticationApi' in window) {
// When running on desktop we want to have option to save access token to a file,
// so it can be reused later when issuing requests to the Cloud API.
//
// Note: Wrapping this function in an arrow function ensures that the current Authentication API
// is always used.
- saveAccessToken = (accessToken: SaveAccessTokenPayload | null) => {
+ saveAccessToken = (accessToken: saveAccessTokenModule.AccessToken | null) => {
window.authenticationApi.saveAccessToken(accessToken)
}
}
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Alert/Alert.tsx b/app/dashboard/src/components/AriaComponents/Alert/Alert.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Alert/Alert.tsx
rename to app/dashboard/src/components/AriaComponents/Alert/Alert.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Alert/index.ts b/app/dashboard/src/components/AriaComponents/Alert/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Alert/index.ts
rename to app/dashboard/src/components/AriaComponents/Alert/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/Button.tsx b/app/dashboard/src/components/AriaComponents/Button/Button.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/Button.tsx
rename to app/dashboard/src/components/AriaComponents/Button/Button.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/ButtonGroup.tsx b/app/dashboard/src/components/AriaComponents/Button/ButtonGroup.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/ButtonGroup.tsx
rename to app/dashboard/src/components/AriaComponents/Button/ButtonGroup.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/CloseButton.tsx b/app/dashboard/src/components/AriaComponents/Button/CloseButton.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/CloseButton.tsx
rename to app/dashboard/src/components/AriaComponents/Button/CloseButton.tsx
index 5c8286e8a9a..c0bd71aa56c 100644
--- a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/CloseButton.tsx
+++ b/app/dashboard/src/components/AriaComponents/Button/CloseButton.tsx
@@ -2,7 +2,7 @@
import * as React from 'react'
-import Dismiss from 'enso-assets/dismiss.svg'
+import Dismiss from '#/assets/dismiss.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/CopyButton.tsx b/app/dashboard/src/components/AriaComponents/Button/CopyButton.tsx
similarity index 93%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/CopyButton.tsx
rename to app/dashboard/src/components/AriaComponents/Button/CopyButton.tsx
index 69bf7a38b44..d75b1dfcd0c 100644
--- a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/CopyButton.tsx
+++ b/app/dashboard/src/components/AriaComponents/Button/CopyButton.tsx
@@ -1,9 +1,9 @@
/** @file A button that copies text to the clipboard. */
import * as React from 'react'
-import Error from 'enso-assets/cross.svg'
-import CopyIcon from 'enso-assets/duplicate.svg'
-import Done from 'enso-assets/tick.svg'
+import Error from '#/assets/cross.svg'
+import CopyIcon from '#/assets/duplicate.svg'
+import Done from '#/assets/tick.svg'
import * as copyHook from '#/hooks/copyHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/index.ts b/app/dashboard/src/components/AriaComponents/Button/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Button/index.ts
rename to app/dashboard/src/components/AriaComponents/Button/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/CopyBlock/CopyBlock.tsx b/app/dashboard/src/components/AriaComponents/CopyBlock/CopyBlock.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/CopyBlock/CopyBlock.tsx
rename to app/dashboard/src/components/AriaComponents/CopyBlock/CopyBlock.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/CopyBlock/index.ts b/app/dashboard/src/components/AriaComponents/CopyBlock/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/CopyBlock/index.ts
rename to app/dashboard/src/components/AriaComponents/CopyBlock/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/Close.tsx b/app/dashboard/src/components/AriaComponents/Dialog/Close.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/Close.tsx
rename to app/dashboard/src/components/AriaComponents/Dialog/Close.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/Dialog.tsx b/app/dashboard/src/components/AriaComponents/Dialog/Dialog.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/Dialog.tsx
rename to app/dashboard/src/components/AriaComponents/Dialog/Dialog.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/DialogProvider.tsx b/app/dashboard/src/components/AriaComponents/Dialog/DialogProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/DialogProvider.tsx
rename to app/dashboard/src/components/AriaComponents/Dialog/DialogProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/DialogStackProvider.tsx b/app/dashboard/src/components/AriaComponents/Dialog/DialogStackProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/DialogStackProvider.tsx
rename to app/dashboard/src/components/AriaComponents/Dialog/DialogStackProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/DialogTrigger.tsx b/app/dashboard/src/components/AriaComponents/Dialog/DialogTrigger.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/DialogTrigger.tsx
rename to app/dashboard/src/components/AriaComponents/Dialog/DialogTrigger.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/Popover.tsx b/app/dashboard/src/components/AriaComponents/Dialog/Popover.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/Popover.tsx
rename to app/dashboard/src/components/AriaComponents/Dialog/Popover.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/index.ts b/app/dashboard/src/components/AriaComponents/Dialog/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/index.ts
rename to app/dashboard/src/components/AriaComponents/Dialog/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/types.ts b/app/dashboard/src/components/AriaComponents/Dialog/types.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/types.ts
rename to app/dashboard/src/components/AriaComponents/Dialog/types.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/utilities.ts b/app/dashboard/src/components/AriaComponents/Dialog/utilities.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/utilities.ts
rename to app/dashboard/src/components/AriaComponents/Dialog/utilities.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/variants.ts b/app/dashboard/src/components/AriaComponents/Dialog/variants.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Dialog/variants.ts
rename to app/dashboard/src/components/AriaComponents/Dialog/variants.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/Form.tsx b/app/dashboard/src/components/AriaComponents/Form/Form.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/Form.tsx
rename to app/dashboard/src/components/AriaComponents/Form/Form.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/Field.tsx b/app/dashboard/src/components/AriaComponents/Form/components/Field.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/Field.tsx
rename to app/dashboard/src/components/AriaComponents/Form/components/Field.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/FormError.tsx b/app/dashboard/src/components/AriaComponents/Form/components/FormError.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/FormError.tsx
rename to app/dashboard/src/components/AriaComponents/Form/components/FormError.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/Reset.tsx b/app/dashboard/src/components/AriaComponents/Form/components/Reset.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/Reset.tsx
rename to app/dashboard/src/components/AriaComponents/Form/components/Reset.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/Submit.tsx b/app/dashboard/src/components/AriaComponents/Form/components/Submit.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/Submit.tsx
rename to app/dashboard/src/components/AriaComponents/Form/components/Submit.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/index.ts b/app/dashboard/src/components/AriaComponents/Form/components/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/index.ts
rename to app/dashboard/src/components/AriaComponents/Form/components/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/schema.ts b/app/dashboard/src/components/AriaComponents/Form/components/schema.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/schema.ts
rename to app/dashboard/src/components/AriaComponents/Form/components/schema.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/types.ts b/app/dashboard/src/components/AriaComponents/Form/components/types.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/types.ts
rename to app/dashboard/src/components/AriaComponents/Form/components/types.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useField.ts b/app/dashboard/src/components/AriaComponents/Form/components/useField.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useField.ts
rename to app/dashboard/src/components/AriaComponents/Form/components/useField.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useForm.ts b/app/dashboard/src/components/AriaComponents/Form/components/useForm.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useForm.ts
rename to app/dashboard/src/components/AriaComponents/Form/components/useForm.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useFormContext.tsx b/app/dashboard/src/components/AriaComponents/Form/components/useFormContext.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useFormContext.tsx
rename to app/dashboard/src/components/AriaComponents/Form/components/useFormContext.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useFormSchema.tsx b/app/dashboard/src/components/AriaComponents/Form/components/useFormSchema.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/components/useFormSchema.tsx
rename to app/dashboard/src/components/AriaComponents/Form/components/useFormSchema.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/index.ts b/app/dashboard/src/components/AriaComponents/Form/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/index.ts
rename to app/dashboard/src/components/AriaComponents/Form/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/styles.ts b/app/dashboard/src/components/AriaComponents/Form/styles.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/styles.ts
rename to app/dashboard/src/components/AriaComponents/Form/styles.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/types.ts b/app/dashboard/src/components/AriaComponents/Form/types.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Form/types.ts
rename to app/dashboard/src/components/AriaComponents/Form/types.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableContentEditableInput.tsx b/app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableContentEditableInput.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableContentEditableInput.tsx
rename to app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableContentEditableInput.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableInput.tsx b/app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableInput.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableInput.tsx
rename to app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/ResizableInput.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/index.ts b/app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/index.ts
rename to app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/variants.ts b/app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/variants.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/ResizableInput/variants.ts
rename to app/dashboard/src/components/AriaComponents/Inputs/ResizableInput/variants.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/index.ts b/app/dashboard/src/components/AriaComponents/Inputs/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Inputs/index.ts
rename to app/dashboard/src/components/AriaComponents/Inputs/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/Radio.tsx b/app/dashboard/src/components/AriaComponents/Radio/Radio.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/Radio.tsx
rename to app/dashboard/src/components/AriaComponents/Radio/Radio.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/RadioGroup.tsx b/app/dashboard/src/components/AriaComponents/Radio/RadioGroup.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/RadioGroup.tsx
rename to app/dashboard/src/components/AriaComponents/Radio/RadioGroup.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/RadioGroupContext.tsx b/app/dashboard/src/components/AriaComponents/Radio/RadioGroupContext.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/RadioGroupContext.tsx
rename to app/dashboard/src/components/AriaComponents/Radio/RadioGroupContext.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/index.ts b/app/dashboard/src/components/AriaComponents/Radio/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Radio/index.ts
rename to app/dashboard/src/components/AriaComponents/Radio/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Separator.tsx b/app/dashboard/src/components/AriaComponents/Separator.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Separator.tsx
rename to app/dashboard/src/components/AriaComponents/Separator.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/Text.tsx b/app/dashboard/src/components/AriaComponents/Text/Text.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/Text.tsx
rename to app/dashboard/src/components/AriaComponents/Text/Text.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/TextProvider.tsx b/app/dashboard/src/components/AriaComponents/Text/TextProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/TextProvider.tsx
rename to app/dashboard/src/components/AriaComponents/Text/TextProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/index.ts b/app/dashboard/src/components/AriaComponents/Text/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/index.ts
rename to app/dashboard/src/components/AriaComponents/Text/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/useVisualTooltip.tsx b/app/dashboard/src/components/AriaComponents/Text/useVisualTooltip.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Text/useVisualTooltip.tsx
rename to app/dashboard/src/components/AriaComponents/Text/useVisualTooltip.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Tooltip/Tooltip.tsx b/app/dashboard/src/components/AriaComponents/Tooltip/Tooltip.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Tooltip/Tooltip.tsx
rename to app/dashboard/src/components/AriaComponents/Tooltip/Tooltip.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/Tooltip/index.ts b/app/dashboard/src/components/AriaComponents/Tooltip/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/Tooltip/index.ts
rename to app/dashboard/src/components/AriaComponents/Tooltip/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/VisuallyHidden.tsx b/app/dashboard/src/components/AriaComponents/VisuallyHidden.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/VisuallyHidden.tsx
rename to app/dashboard/src/components/AriaComponents/VisuallyHidden.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/AriaComponents/index.ts b/app/dashboard/src/components/AriaComponents/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/AriaComponents/index.ts
rename to app/dashboard/src/components/AriaComponents/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/Autocomplete.tsx b/app/dashboard/src/components/Autocomplete.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Autocomplete.tsx
rename to app/dashboard/src/components/Autocomplete.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/ColorPicker.tsx b/app/dashboard/src/components/ColorPicker.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/ColorPicker.tsx
rename to app/dashboard/src/components/ColorPicker.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/ContextMenu.tsx b/app/dashboard/src/components/ContextMenu.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/ContextMenu.tsx
rename to app/dashboard/src/components/ContextMenu.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/ContextMenuEntry.tsx b/app/dashboard/src/components/ContextMenuEntry.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/ContextMenuEntry.tsx
rename to app/dashboard/src/components/ContextMenuEntry.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/ContextMenus.tsx b/app/dashboard/src/components/ContextMenus.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/ContextMenus.tsx
rename to app/dashboard/src/components/ContextMenus.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/ControlledInput.tsx b/app/dashboard/src/components/ControlledInput.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/ControlledInput.tsx
rename to app/dashboard/src/components/ControlledInput.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/DateInput.tsx b/app/dashboard/src/components/DateInput.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/components/DateInput.tsx
rename to app/dashboard/src/components/DateInput.tsx
index 13574727883..602d23f3220 100644
--- a/app/ide-desktop/lib/dashboard/src/components/DateInput.tsx
+++ b/app/dashboard/src/components/DateInput.tsx
@@ -1,9 +1,9 @@
/** @file An input that outputs a {@link Date}. */
import * as React from 'react'
-import CrossIcon from 'enso-assets/cross.svg'
-import FolderArrowDoubleIcon from 'enso-assets/folder_arrow_double.svg'
-import FolderArrowIcon from 'enso-assets/folder_arrow.svg'
+import CrossIcon from '#/assets/cross.svg'
+import FolderArrowDoubleIcon from '#/assets/folder_arrow_double.svg'
+import FolderArrowIcon from '#/assets/folder_arrow.svg'
import * as focusHooks from '#/hooks/focusHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Devtools/EnsoDevtools.tsx b/app/dashboard/src/components/Devtools/EnsoDevtools.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/Devtools/EnsoDevtools.tsx
rename to app/dashboard/src/components/Devtools/EnsoDevtools.tsx
index 4d164366abf..faf96ee4fea 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Devtools/EnsoDevtools.tsx
+++ b/app/dashboard/src/components/Devtools/EnsoDevtools.tsx
@@ -7,7 +7,7 @@ import * as React from 'react'
import * as reactQuery from '@tanstack/react-query'
-import DevtoolsLogo from 'enso-assets/enso_logo.svg'
+import DevtoolsLogo from '#/assets/enso_logo.svg'
import * as billing from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Devtools/ReactQueryDevtools.tsx b/app/dashboard/src/components/Devtools/ReactQueryDevtools.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Devtools/ReactQueryDevtools.tsx
rename to app/dashboard/src/components/Devtools/ReactQueryDevtools.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Devtools/index.ts b/app/dashboard/src/components/Devtools/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Devtools/index.ts
rename to app/dashboard/src/components/Devtools/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/Dropdown.tsx b/app/dashboard/src/components/Dropdown.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/Dropdown.tsx
rename to app/dashboard/src/components/Dropdown.tsx
index 22caff98666..aa559b37dd0 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Dropdown.tsx
+++ b/app/dashboard/src/components/Dropdown.tsx
@@ -1,8 +1,8 @@
/** @file A styled dropdown. */
import * as React from 'react'
-import CheckMarkIcon from 'enso-assets/check_mark.svg'
-import FolderArrowIcon from 'enso-assets/folder_arrow.svg'
+import CheckMarkIcon from '#/assets/check_mark.svg'
+import FolderArrowIcon from '#/assets/folder_arrow.svg'
import FocusRing from '#/components/styled/FocusRing'
import SvgMask from '#/components/SvgMask'
diff --git a/app/ide-desktop/lib/dashboard/src/components/EditableSpan.tsx b/app/dashboard/src/components/EditableSpan.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/components/EditableSpan.tsx
rename to app/dashboard/src/components/EditableSpan.tsx
index 062d165d954..aa1f84dfdc2 100644
--- a/app/ide-desktop/lib/dashboard/src/components/EditableSpan.tsx
+++ b/app/dashboard/src/components/EditableSpan.tsx
@@ -1,8 +1,8 @@
/** @file A text `` which turns into an `input` when desired. */
import * as React from 'react'
-import CrossIcon from 'enso-assets/cross.svg'
-import TickIcon from 'enso-assets/tick.svg'
+import CrossIcon from '#/assets/cross.svg'
+import TickIcon from '#/assets/tick.svg'
import * as eventCallback from '#/hooks/eventCallbackHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/ErrorBoundary.tsx b/app/dashboard/src/components/ErrorBoundary.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/ErrorBoundary.tsx
rename to app/dashboard/src/components/ErrorBoundary.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Input.tsx b/app/dashboard/src/components/Input.tsx
similarity index 92%
rename from app/ide-desktop/lib/dashboard/src/components/Input.tsx
rename to app/dashboard/src/components/Input.tsx
index 9b95dde4af4..cc382baf7fd 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Input.tsx
+++ b/app/dashboard/src/components/Input.tsx
@@ -1,8 +1,8 @@
/** @file A styled input that includes an icon. */
import * as React from 'react'
-import EyeCrossedIcon from 'enso-assets/eye_crossed.svg'
-import EyeIcon from 'enso-assets/eye.svg'
+import EyeCrossedIcon from '#/assets/eye_crossed.svg'
+import EyeIcon from '#/assets/eye.svg'
import type * as controlledInput from '#/components/ControlledInput'
import ControlledInput from '#/components/ControlledInput'
diff --git a/app/ide-desktop/lib/dashboard/src/components/JSONSchemaInput.tsx b/app/dashboard/src/components/JSONSchemaInput.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/JSONSchemaInput.tsx
rename to app/dashboard/src/components/JSONSchemaInput.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Link.tsx b/app/dashboard/src/components/Link.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Link.tsx
rename to app/dashboard/src/components/Link.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Loader.tsx b/app/dashboard/src/components/Loader.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Loader.tsx
rename to app/dashboard/src/components/Loader.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/MenuEntry.tsx b/app/dashboard/src/components/MenuEntry.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/MenuEntry.tsx
rename to app/dashboard/src/components/MenuEntry.tsx
index 4982412b267..b505cfd5db4 100644
--- a/app/ide-desktop/lib/dashboard/src/components/MenuEntry.tsx
+++ b/app/dashboard/src/components/MenuEntry.tsx
@@ -1,10 +1,11 @@
/** @file An entry in a menu. */
import * as React from 'react'
-import BlankIcon from 'enso-assets/blank.svg'
import * as detect from 'enso-common/src/detect'
import type * as text from 'enso-common/src/text'
+import BlankIcon from '#/assets/blank.svg'
+
import type * as inputBindings from '#/configurations/inputBindings'
import * as focusHooks from '#/hooks/focusHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Modal.tsx b/app/dashboard/src/components/Modal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Modal.tsx
rename to app/dashboard/src/components/Modal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/OfflineNotificationManager.tsx b/app/dashboard/src/components/OfflineNotificationManager.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/OfflineNotificationManager.tsx
rename to app/dashboard/src/components/OfflineNotificationManager.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Page.tsx b/app/dashboard/src/components/Page.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Page.tsx
rename to app/dashboard/src/components/Page.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/ContextMenuEntry.tsx b/app/dashboard/src/components/Paywall/ContextMenuEntry.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/ContextMenuEntry.tsx
rename to app/dashboard/src/components/Paywall/ContextMenuEntry.tsx
index 9b1d3b355bb..2b50630c66b 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Paywall/ContextMenuEntry.tsx
+++ b/app/dashboard/src/components/Paywall/ContextMenuEntry.tsx
@@ -6,7 +6,7 @@
import * as React from 'react'
-import LockIcon from 'enso-assets/lock.svg'
+import LockIcon from '#/assets/lock.svg'
import type * as billingHooks from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallAlert.tsx b/app/dashboard/src/components/Paywall/PaywallAlert.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallAlert.tsx
rename to app/dashboard/src/components/Paywall/PaywallAlert.tsx
index 11007f8386f..0267f01a4fb 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallAlert.tsx
+++ b/app/dashboard/src/components/Paywall/PaywallAlert.tsx
@@ -8,7 +8,7 @@ import * as React from 'react'
import clsx from 'clsx'
-import LockIcon from 'enso-assets/lock.svg'
+import LockIcon from '#/assets/lock.svg'
import type * as billingHooks from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallDialog.tsx b/app/dashboard/src/components/Paywall/PaywallDialog.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallDialog.tsx
rename to app/dashboard/src/components/Paywall/PaywallDialog.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallDialogButton.tsx b/app/dashboard/src/components/Paywall/PaywallDialogButton.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallDialogButton.tsx
rename to app/dashboard/src/components/Paywall/PaywallDialogButton.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallScreen.tsx b/app/dashboard/src/components/Paywall/PaywallScreen.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/PaywallScreen.tsx
rename to app/dashboard/src/components/Paywall/PaywallScreen.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/UpgradeButton.tsx b/app/dashboard/src/components/Paywall/UpgradeButton.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/UpgradeButton.tsx
rename to app/dashboard/src/components/Paywall/UpgradeButton.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallBulletPoints.tsx b/app/dashboard/src/components/Paywall/components/PaywallBulletPoints.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallBulletPoints.tsx
rename to app/dashboard/src/components/Paywall/components/PaywallBulletPoints.tsx
index ddcb70fdb6b..4c25669fc93 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallBulletPoints.tsx
+++ b/app/dashboard/src/components/Paywall/components/PaywallBulletPoints.tsx
@@ -7,9 +7,10 @@ import * as React from 'react'
import * as tw from 'tailwind-merge'
-import Check from 'enso-assets/check_mark.svg'
import type * as text from 'enso-common/src/text'
+import Check from '#/assets/check_mark.svg'
+
import * as textProvider from '#/providers/TextProvider'
import * as ariaComponents from '#/components/AriaComponents'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallButton.tsx b/app/dashboard/src/components/Paywall/components/PaywallButton.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallButton.tsx
rename to app/dashboard/src/components/Paywall/components/PaywallButton.tsx
index 70787954702..4fa45f1dd32 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallButton.tsx
+++ b/app/dashboard/src/components/Paywall/components/PaywallButton.tsx
@@ -5,7 +5,7 @@
*/
import * as React from 'react'
-import PaywallBlocked from 'enso-assets/lock.svg'
+import PaywallBlocked from '#/assets/lock.svg'
import * as billingHooks from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallLock.tsx b/app/dashboard/src/components/Paywall/components/PaywallLock.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallLock.tsx
rename to app/dashboard/src/components/Paywall/components/PaywallLock.tsx
index 3bb2b146239..be4bdbba749 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Paywall/components/PaywallLock.tsx
+++ b/app/dashboard/src/components/Paywall/components/PaywallLock.tsx
@@ -3,7 +3,7 @@
*/
import * as tw from 'tailwind-merge'
-import LockIcon from 'enso-assets/lock.svg'
+import LockIcon from '#/assets/lock.svg'
import * as billingHooks from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/components/index.ts b/app/dashboard/src/components/Paywall/components/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/components/index.ts
rename to app/dashboard/src/components/Paywall/components/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/Paywall/index.ts b/app/dashboard/src/components/Paywall/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Paywall/index.ts
rename to app/dashboard/src/components/Paywall/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/Portal/Portal.tsx b/app/dashboard/src/components/Portal/Portal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Portal/Portal.tsx
rename to app/dashboard/src/components/Portal/Portal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Portal/PortalProvider.ts b/app/dashboard/src/components/Portal/PortalProvider.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Portal/PortalProvider.ts
rename to app/dashboard/src/components/Portal/PortalProvider.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/Portal/index.ts b/app/dashboard/src/components/Portal/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Portal/index.ts
rename to app/dashboard/src/components/Portal/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/Portal/types.ts b/app/dashboard/src/components/Portal/types.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Portal/types.ts
rename to app/dashboard/src/components/Portal/types.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/Portal/usePortal.ts b/app/dashboard/src/components/Portal/usePortal.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Portal/usePortal.ts
rename to app/dashboard/src/components/Portal/usePortal.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/README.md b/app/dashboard/src/components/README.md
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/README.md
rename to app/dashboard/src/components/README.md
diff --git a/app/ide-desktop/lib/dashboard/src/components/Result.tsx b/app/dashboard/src/components/Result.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/components/Result.tsx
rename to app/dashboard/src/components/Result.tsx
index e0b5cf0cb30..405223864e0 100644
--- a/app/ide-desktop/lib/dashboard/src/components/Result.tsx
+++ b/app/dashboard/src/components/Result.tsx
@@ -3,8 +3,8 @@ import * as React from 'react'
import * as twv from 'tailwind-variants'
-import Success from 'enso-assets/check_mark.svg'
-import Error from 'enso-assets/cross.svg'
+import Success from '#/assets/check_mark.svg'
+import Error from '#/assets/cross.svg'
import * as ariaComponents from '#/components/AriaComponents'
import * as loader from '#/components/Loader'
diff --git a/app/ide-desktop/lib/dashboard/src/components/Root.tsx b/app/dashboard/src/components/Root.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Root.tsx
rename to app/dashboard/src/components/Root.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/SelectionBrush.tsx b/app/dashboard/src/components/SelectionBrush.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/SelectionBrush.tsx
rename to app/dashboard/src/components/SelectionBrush.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Spinner.tsx b/app/dashboard/src/components/Spinner.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Spinner.tsx
rename to app/dashboard/src/components/Spinner.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/StatelessSpinner.tsx b/app/dashboard/src/components/StatelessSpinner.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/StatelessSpinner.tsx
rename to app/dashboard/src/components/StatelessSpinner.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/SubmitButton.tsx b/app/dashboard/src/components/SubmitButton.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/SubmitButton.tsx
rename to app/dashboard/src/components/SubmitButton.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Suspense.tsx b/app/dashboard/src/components/Suspense.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Suspense.tsx
rename to app/dashboard/src/components/Suspense.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/SvgIcon.tsx b/app/dashboard/src/components/SvgIcon.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/SvgIcon.tsx
rename to app/dashboard/src/components/SvgIcon.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/SvgMask.tsx b/app/dashboard/src/components/SvgMask.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/SvgMask.tsx
rename to app/dashboard/src/components/SvgMask.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/TextLink.tsx b/app/dashboard/src/components/TextLink.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/TextLink.tsx
rename to app/dashboard/src/components/TextLink.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/Twemoji.tsx b/app/dashboard/src/components/Twemoji.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/Twemoji.tsx
rename to app/dashboard/src/components/Twemoji.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/aria.tsx b/app/dashboard/src/components/aria.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/aria.tsx
rename to app/dashboard/src/components/aria.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/AssetIcon.tsx b/app/dashboard/src/components/dashboard/AssetIcon.tsx
similarity index 85%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/AssetIcon.tsx
rename to app/dashboard/src/components/dashboard/AssetIcon.tsx
index d3b454692ee..9aaaa11614f 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/AssetIcon.tsx
+++ b/app/dashboard/src/components/dashboard/AssetIcon.tsx
@@ -1,11 +1,11 @@
/** @file Displays a non-interactable icon for an asset based on its type and name. */
import * as React from 'react'
-import BlankIcon from 'enso-assets/blank.svg'
-import DatalinkIcon from 'enso-assets/datalink.svg'
-import FolderIcon from 'enso-assets/folder.svg'
-import KeyIcon from 'enso-assets/key.svg'
-import NetworkIcon from 'enso-assets/network.svg'
+import BlankIcon from '#/assets/blank.svg'
+import DatalinkIcon from '#/assets/datalink.svg'
+import FolderIcon from '#/assets/folder.svg'
+import KeyIcon from '#/assets/key.svg'
+import NetworkIcon from '#/assets/network.svg'
import SvgMask from '#/components/SvgMask'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/AssetRow.tsx b/app/dashboard/src/components/dashboard/AssetRow.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/AssetRow.tsx
rename to app/dashboard/src/components/dashboard/AssetRow.tsx
index b95d3cbb1d9..183a5314df4 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/AssetRow.tsx
+++ b/app/dashboard/src/components/dashboard/AssetRow.tsx
@@ -1,7 +1,7 @@
/** @file A table row for an arbitrary asset. */
import * as React from 'react'
-import BlankIcon from 'enso-assets/blank.svg'
+import BlankIcon from '#/assets/blank.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as dragAndDropHooks from '#/hooks/dragAndDropHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/AssetRow/assetRowUtils.tsx b/app/dashboard/src/components/dashboard/AssetRow/assetRowUtils.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/AssetRow/assetRowUtils.tsx
rename to app/dashboard/src/components/dashboard/AssetRow/assetRowUtils.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/AssetSummary.tsx b/app/dashboard/src/components/dashboard/AssetSummary.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/AssetSummary.tsx
rename to app/dashboard/src/components/dashboard/AssetSummary.tsx
index f691e4d5b21..b2c0aa033df 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/AssetSummary.tsx
+++ b/app/dashboard/src/components/dashboard/AssetSummary.tsx
@@ -1,7 +1,7 @@
/** @file Displays a few details of an asset. */
import * as React from 'react'
-import BreadcrumbArrowIcon from 'enso-assets/breadcrumb_arrow.svg'
+import BreadcrumbArrowIcon from '#/assets/breadcrumb_arrow.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/DatalinkInput.tsx b/app/dashboard/src/components/dashboard/DatalinkInput.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/DatalinkInput.tsx
rename to app/dashboard/src/components/dashboard/DatalinkInput.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/DatalinkNameColumn.tsx b/app/dashboard/src/components/dashboard/DatalinkNameColumn.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/DatalinkNameColumn.tsx
rename to app/dashboard/src/components/dashboard/DatalinkNameColumn.tsx
index 0388c520d5a..27f481d1fdd 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/DatalinkNameColumn.tsx
+++ b/app/dashboard/src/components/dashboard/DatalinkNameColumn.tsx
@@ -1,7 +1,7 @@
/** @file The icon and name of a {@link backendModule.SecretAsset}. */
import * as React from 'react'
-import DatalinkIcon from 'enso-assets/datalink.svg'
+import DatalinkIcon from '#/assets/datalink.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as setAssetHooks from '#/hooks/setAssetHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/DirectoryNameColumn.tsx b/app/dashboard/src/components/dashboard/DirectoryNameColumn.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/DirectoryNameColumn.tsx
rename to app/dashboard/src/components/dashboard/DirectoryNameColumn.tsx
index 4e70f6c7391..72ebd0e6c0a 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/DirectoryNameColumn.tsx
+++ b/app/dashboard/src/components/dashboard/DirectoryNameColumn.tsx
@@ -1,8 +1,8 @@
/** @file The icon and name of a {@link backendModule.DirectoryAsset}. */
import * as React from 'react'
-import FolderArrowIcon from 'enso-assets/folder_arrow.svg'
-import FolderIcon from 'enso-assets/folder.svg'
+import FolderArrowIcon from '#/assets/folder_arrow.svg'
+import FolderIcon from '#/assets/folder.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as setAssetHooks from '#/hooks/setAssetHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/FileNameColumn.tsx b/app/dashboard/src/components/dashboard/FileNameColumn.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/FileNameColumn.tsx
rename to app/dashboard/src/components/dashboard/FileNameColumn.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/KeyboardShortcut.tsx b/app/dashboard/src/components/dashboard/KeyboardShortcut.tsx
similarity index 94%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/KeyboardShortcut.tsx
rename to app/dashboard/src/components/dashboard/KeyboardShortcut.tsx
index f440b5f192a..b33d4dee702 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/KeyboardShortcut.tsx
+++ b/app/dashboard/src/components/dashboard/KeyboardShortcut.tsx
@@ -1,14 +1,15 @@
/** @file A visual representation of a keyboard shortcut. */
import * as React from 'react'
-import CommandKeyIcon from 'enso-assets/command_key.svg'
-import CtrlKeyIcon from 'enso-assets/ctrl_key.svg'
-import OptionKeyIcon from 'enso-assets/option_key.svg'
-import ShiftKeyIcon from 'enso-assets/shift_key.svg'
-import WindowsKeyIcon from 'enso-assets/windows_key.svg'
import * as detect from 'enso-common/src/detect'
import type * as text from 'enso-common/src/text'
+import CommandKeyIcon from '#/assets/command_key.svg'
+import CtrlKeyIcon from '#/assets/ctrl_key.svg'
+import OptionKeyIcon from '#/assets/option_key.svg'
+import ShiftKeyIcon from '#/assets/shift_key.svg'
+import WindowsKeyIcon from '#/assets/windows_key.svg'
+
import type * as dashboardInputBindings from '#/configurations/inputBindings'
import * as inputBindingsProvider from '#/providers/InputBindingsProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/Label.tsx b/app/dashboard/src/components/dashboard/Label.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/Label.tsx
rename to app/dashboard/src/components/dashboard/Label.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/Permission.tsx b/app/dashboard/src/components/dashboard/Permission.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/Permission.tsx
rename to app/dashboard/src/components/dashboard/Permission.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/PermissionDisplay.tsx b/app/dashboard/src/components/dashboard/PermissionDisplay.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/PermissionDisplay.tsx
rename to app/dashboard/src/components/dashboard/PermissionDisplay.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/PermissionSelector.tsx b/app/dashboard/src/components/dashboard/PermissionSelector.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/PermissionSelector.tsx
rename to app/dashboard/src/components/dashboard/PermissionSelector.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/PermissionTypeSelector.tsx b/app/dashboard/src/components/dashboard/PermissionTypeSelector.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/PermissionTypeSelector.tsx
rename to app/dashboard/src/components/dashboard/PermissionTypeSelector.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/ProjectIcon.tsx b/app/dashboard/src/components/dashboard/ProjectIcon.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/ProjectIcon.tsx
rename to app/dashboard/src/components/dashboard/ProjectIcon.tsx
index 05128909f35..658d69c9233 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/ProjectIcon.tsx
+++ b/app/dashboard/src/components/dashboard/ProjectIcon.tsx
@@ -3,9 +3,9 @@ import * as React from 'react'
import * as reactQuery from '@tanstack/react-query'
-import ArrowUpIcon from 'enso-assets/arrow_up.svg'
-import PlayIcon from 'enso-assets/play.svg'
-import StopIcon from 'enso-assets/stop.svg'
+import ArrowUpIcon from '#/assets/arrow_up.svg'
+import PlayIcon from '#/assets/play.svg'
+import StopIcon from '#/assets/stop.svg'
import * as projectHooks from '#/hooks/projectHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/ProjectNameColumn.tsx b/app/dashboard/src/components/dashboard/ProjectNameColumn.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/ProjectNameColumn.tsx
rename to app/dashboard/src/components/dashboard/ProjectNameColumn.tsx
index cf89b9cc48f..25c460f9b84 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/ProjectNameColumn.tsx
+++ b/app/dashboard/src/components/dashboard/ProjectNameColumn.tsx
@@ -1,7 +1,7 @@
/** @file The icon and name of a {@link backendModule.ProjectAsset}. */
import * as React from 'react'
-import NetworkIcon from 'enso-assets/network.svg'
+import NetworkIcon from '#/assets/network.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as projectHooks from '#/hooks/projectHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/SecretNameColumn.tsx b/app/dashboard/src/components/dashboard/SecretNameColumn.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/SecretNameColumn.tsx
rename to app/dashboard/src/components/dashboard/SecretNameColumn.tsx
index 173f01e8604..5943ebb760a 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/SecretNameColumn.tsx
+++ b/app/dashboard/src/components/dashboard/SecretNameColumn.tsx
@@ -1,7 +1,7 @@
/** @file The icon and name of a {@link backendModule.SecretAsset}. */
import * as React from 'react'
-import KeyIcon from 'enso-assets/key.svg'
+import KeyIcon from '#/assets/key.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as setAssetHooks from '#/hooks/setAssetHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/TheModal.tsx b/app/dashboard/src/components/dashboard/TheModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/TheModal.tsx
rename to app/dashboard/src/components/dashboard/TheModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column.ts b/app/dashboard/src/components/dashboard/column.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column.ts
rename to app/dashboard/src/components/dashboard/column.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/DocsColumn.tsx b/app/dashboard/src/components/dashboard/column/DocsColumn.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column/DocsColumn.tsx
rename to app/dashboard/src/components/dashboard/column/DocsColumn.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/LabelsColumn.tsx b/app/dashboard/src/components/dashboard/column/LabelsColumn.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column/LabelsColumn.tsx
rename to app/dashboard/src/components/dashboard/column/LabelsColumn.tsx
index d4b6ce31374..b7e28a65c14 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/LabelsColumn.tsx
+++ b/app/dashboard/src/components/dashboard/column/LabelsColumn.tsx
@@ -1,7 +1,7 @@
/** @file A column listing the labels on this asset. */
import * as React from 'react'
-import Plus2Icon from 'enso-assets/plus2.svg'
+import Plus2Icon from '#/assets/plus2.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/ModifiedColumn.tsx b/app/dashboard/src/components/dashboard/column/ModifiedColumn.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column/ModifiedColumn.tsx
rename to app/dashboard/src/components/dashboard/column/ModifiedColumn.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/NameColumn.tsx b/app/dashboard/src/components/dashboard/column/NameColumn.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column/NameColumn.tsx
rename to app/dashboard/src/components/dashboard/column/NameColumn.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/PlaceholderColumn.tsx b/app/dashboard/src/components/dashboard/column/PlaceholderColumn.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column/PlaceholderColumn.tsx
rename to app/dashboard/src/components/dashboard/column/PlaceholderColumn.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/SharedWithColumn.tsx b/app/dashboard/src/components/dashboard/column/SharedWithColumn.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column/SharedWithColumn.tsx
rename to app/dashboard/src/components/dashboard/column/SharedWithColumn.tsx
index d6702b2ad7e..9583e28d2e5 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/SharedWithColumn.tsx
+++ b/app/dashboard/src/components/dashboard/column/SharedWithColumn.tsx
@@ -1,7 +1,7 @@
/** @file A column listing the users with which this asset is shared. */
import * as React from 'react'
-import Plus2Icon from 'enso-assets/plus2.svg'
+import Plus2Icon from '#/assets/plus2.svg'
import * as billingHooks from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/columnUtils.ts b/app/dashboard/src/components/dashboard/column/columnUtils.ts
similarity index 90%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/column/columnUtils.ts
rename to app/dashboard/src/components/dashboard/column/columnUtils.ts
index a3865d75270..7dce7ce601e 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/column/columnUtils.ts
+++ b/app/dashboard/src/components/dashboard/column/columnUtils.ts
@@ -1,13 +1,14 @@
/** @file Types and constants related to `Column`s. */
-import AccessedByProjectsIcon from 'enso-assets/accessed_by_projects.svg'
-import AccessedDataIcon from 'enso-assets/accessed_data.svg'
-import BlankIcon from 'enso-assets/blank.svg'
-import DocsIcon from 'enso-assets/docs.svg'
-import PeopleIcon from 'enso-assets/people.svg'
-import TagIcon from 'enso-assets/tag.svg'
-import TimeIcon from 'enso-assets/time.svg'
import type * as text from 'enso-common/src/text'
+import AccessedByProjectsIcon from '#/assets/accessed_by_projects.svg'
+import AccessedDataIcon from '#/assets/accessed_data.svg'
+import BlankIcon from '#/assets/blank.svg'
+import DocsIcon from '#/assets/docs.svg'
+import PeopleIcon from '#/assets/people.svg'
+import TagIcon from '#/assets/tag.svg'
+import TimeIcon from '#/assets/time.svg'
+
import * as backend from '#/services/Backend'
// =============
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading.ts b/app/dashboard/src/components/dashboard/columnHeading.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading.ts
rename to app/dashboard/src/components/dashboard/columnHeading.ts
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/AccessedByProjectsColumnHeading.tsx b/app/dashboard/src/components/dashboard/columnHeading/AccessedByProjectsColumnHeading.tsx
similarity index 93%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/AccessedByProjectsColumnHeading.tsx
rename to app/dashboard/src/components/dashboard/columnHeading/AccessedByProjectsColumnHeading.tsx
index 1fdb63de68e..9db57e47b3e 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/AccessedByProjectsColumnHeading.tsx
+++ b/app/dashboard/src/components/dashboard/columnHeading/AccessedByProjectsColumnHeading.tsx
@@ -1,7 +1,7 @@
/** @file A heading for the "Accessed by projects" column. */
import * as React from 'react'
-import AccessedByProjectsIcon from 'enso-assets/accessed_by_projects.svg'
+import AccessedByProjectsIcon from '#/assets/accessed_by_projects.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/AccessedDataColumnHeading.tsx b/app/dashboard/src/components/dashboard/columnHeading/AccessedDataColumnHeading.tsx
similarity index 94%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/AccessedDataColumnHeading.tsx
rename to app/dashboard/src/components/dashboard/columnHeading/AccessedDataColumnHeading.tsx
index 5a4f196c2f1..1f98d940482 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/AccessedDataColumnHeading.tsx
+++ b/app/dashboard/src/components/dashboard/columnHeading/AccessedDataColumnHeading.tsx
@@ -1,7 +1,7 @@
/** @file A heading for the "Accessed data" column. */
import * as React from 'react'
-import AccessedDataIcon from 'enso-assets/accessed_data.svg'
+import AccessedDataIcon from '#/assets/accessed_data.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/DocsColumnHeading.tsx b/app/dashboard/src/components/dashboard/columnHeading/DocsColumnHeading.tsx
similarity index 95%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/DocsColumnHeading.tsx
rename to app/dashboard/src/components/dashboard/columnHeading/DocsColumnHeading.tsx
index a5f0582757b..98e2eb2bb60 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/DocsColumnHeading.tsx
+++ b/app/dashboard/src/components/dashboard/columnHeading/DocsColumnHeading.tsx
@@ -1,7 +1,7 @@
/** @file A heading for the "Docs" column. */
import * as React from 'react'
-import DocsIcon from 'enso-assets/docs.svg'
+import DocsIcon from '#/assets/docs.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/LabelsColumnHeading.tsx b/app/dashboard/src/components/dashboard/columnHeading/LabelsColumnHeading.tsx
similarity index 95%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/LabelsColumnHeading.tsx
rename to app/dashboard/src/components/dashboard/columnHeading/LabelsColumnHeading.tsx
index 78af231d9fb..b3a3145035f 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/LabelsColumnHeading.tsx
+++ b/app/dashboard/src/components/dashboard/columnHeading/LabelsColumnHeading.tsx
@@ -1,7 +1,7 @@
/** @file A heading for the "Labels" column. */
import * as React from 'react'
-import TagIcon from 'enso-assets/tag.svg'
+import TagIcon from '#/assets/tag.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/ModifiedColumnHeading.tsx b/app/dashboard/src/components/dashboard/columnHeading/ModifiedColumnHeading.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/ModifiedColumnHeading.tsx
rename to app/dashboard/src/components/dashboard/columnHeading/ModifiedColumnHeading.tsx
index 12ef4cccb69..219febca971 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/ModifiedColumnHeading.tsx
+++ b/app/dashboard/src/components/dashboard/columnHeading/ModifiedColumnHeading.tsx
@@ -1,8 +1,8 @@
/** @file A heading for the "Modified" column. */
import * as React from 'react'
-import SortAscendingIcon from 'enso-assets/sort_ascending.svg'
-import TimeIcon from 'enso-assets/time.svg'
+import SortAscendingIcon from '#/assets/sort_ascending.svg'
+import TimeIcon from '#/assets/time.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/NameColumnHeading.tsx b/app/dashboard/src/components/dashboard/columnHeading/NameColumnHeading.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/NameColumnHeading.tsx
rename to app/dashboard/src/components/dashboard/columnHeading/NameColumnHeading.tsx
index cf4de76e481..8cbf415c2e5 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/NameColumnHeading.tsx
+++ b/app/dashboard/src/components/dashboard/columnHeading/NameColumnHeading.tsx
@@ -1,7 +1,7 @@
/** @file A heading for the "Name" column. */
import * as React from 'react'
-import SortAscendingIcon from 'enso-assets/sort_ascending.svg'
+import SortAscendingIcon from '#/assets/sort_ascending.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/SharedWithColumnHeading.tsx b/app/dashboard/src/components/dashboard/columnHeading/SharedWithColumnHeading.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/SharedWithColumnHeading.tsx
rename to app/dashboard/src/components/dashboard/columnHeading/SharedWithColumnHeading.tsx
index 7efcd504b48..d58dbe6b8aa 100644
--- a/app/ide-desktop/lib/dashboard/src/components/dashboard/columnHeading/SharedWithColumnHeading.tsx
+++ b/app/dashboard/src/components/dashboard/columnHeading/SharedWithColumnHeading.tsx
@@ -1,7 +1,7 @@
/** @file A heading for the "Shared with" column. */
import * as React from 'react'
-import PeopleIcon from 'enso-assets/people.svg'
+import PeopleIcon from '#/assets/people.svg'
import * as billingHooks from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/Button.tsx b/app/dashboard/src/components/styled/Button.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/Button.tsx
rename to app/dashboard/src/components/styled/Button.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/Checkbox.tsx b/app/dashboard/src/components/styled/Checkbox.tsx
similarity index 94%
rename from app/ide-desktop/lib/dashboard/src/components/styled/Checkbox.tsx
rename to app/dashboard/src/components/styled/Checkbox.tsx
index 6344ce66ba4..ed1e237a079 100644
--- a/app/ide-desktop/lib/dashboard/src/components/styled/Checkbox.tsx
+++ b/app/dashboard/src/components/styled/Checkbox.tsx
@@ -1,7 +1,7 @@
/** @file A styled checkbox. */
import * as React from 'react'
-import CheckMarkIcon from 'enso-assets/check_mark.svg'
+import CheckMarkIcon from '#/assets/check_mark.svg'
import * as aria from '#/components/aria'
import FocusRing from '#/components/styled/FocusRing'
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/FocusArea.tsx b/app/dashboard/src/components/styled/FocusArea.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/FocusArea.tsx
rename to app/dashboard/src/components/styled/FocusArea.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/FocusRing.tsx b/app/dashboard/src/components/styled/FocusRing.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/FocusRing.tsx
rename to app/dashboard/src/components/styled/FocusRing.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/FocusRoot.tsx b/app/dashboard/src/components/styled/FocusRoot.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/FocusRoot.tsx
rename to app/dashboard/src/components/styled/FocusRoot.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/Input.tsx b/app/dashboard/src/components/styled/Input.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/Input.tsx
rename to app/dashboard/src/components/styled/Input.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/RadioGroup.tsx b/app/dashboard/src/components/styled/RadioGroup.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/RadioGroup.tsx
rename to app/dashboard/src/components/styled/RadioGroup.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/Separator.tsx b/app/dashboard/src/components/styled/Separator.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/Separator.tsx
rename to app/dashboard/src/components/styled/Separator.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/SettingsInput.tsx b/app/dashboard/src/components/styled/SettingsInput.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/components/styled/SettingsInput.tsx
rename to app/dashboard/src/components/styled/SettingsInput.tsx
index b901c8e8439..8065c354a55 100644
--- a/app/ide-desktop/lib/dashboard/src/components/styled/SettingsInput.tsx
+++ b/app/dashboard/src/components/styled/SettingsInput.tsx
@@ -1,8 +1,8 @@
/** @file A styled input specific to settings pages. */
import * as React from 'react'
-import EyeCrossedIcon from 'enso-assets/eye_crossed.svg'
-import EyeIcon from 'enso-assets/eye.svg'
+import EyeCrossedIcon from '#/assets/eye_crossed.svg'
+import EyeIcon from '#/assets/eye.svg'
import * as focusHooks from '#/hooks/focusHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/SidebarTabButton.tsx b/app/dashboard/src/components/styled/SidebarTabButton.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/SidebarTabButton.tsx
rename to app/dashboard/src/components/styled/SidebarTabButton.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/components/styled/withFocusScope.tsx b/app/dashboard/src/components/styled/withFocusScope.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/components/styled/withFocusScope.tsx
rename to app/dashboard/src/components/styled/withFocusScope.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/configurations/inputBindings.ts b/app/dashboard/src/configurations/inputBindings.ts
similarity index 75%
rename from app/ide-desktop/lib/dashboard/src/configurations/inputBindings.ts
rename to app/dashboard/src/configurations/inputBindings.ts
index b59e57d117d..7f69edc5b45 100644
--- a/app/ide-desktop/lib/dashboard/src/configurations/inputBindings.ts
+++ b/app/dashboard/src/configurations/inputBindings.ts
@@ -1,35 +1,36 @@
/** @file Shortcuts for the dashboard application. */
-import AddDatalinkIcon from 'enso-assets/add_datalink.svg'
-import AddFolderIcon from 'enso-assets/add_folder.svg'
-import AddKeyIcon from 'enso-assets/add_key.svg'
-import AddNetworkIcon from 'enso-assets/add_network.svg'
-import AppDownloadIcon from 'enso-assets/app_download.svg'
-import ArrowLeftIcon from 'enso-assets/arrow_left.svg'
-import ArrowRightIcon from 'enso-assets/arrow_right.svg'
-import CameraIcon from 'enso-assets/camera.svg'
-import CloseIcon from 'enso-assets/close.svg'
-import CloudToIcon from 'enso-assets/cloud_to.svg'
-import CopyAsPathIcon from 'enso-assets/copy_as_path.svg'
-import CopyIcon from 'enso-assets/copy.svg'
-import DataDownloadIcon from 'enso-assets/data_download.svg'
-import DataUploadIcon from 'enso-assets/data_upload.svg'
-import DuplicateIcon from 'enso-assets/duplicate.svg'
-import LogoIcon from 'enso-assets/enso_logo.svg'
-import OpenInFileBrowserIcon from 'enso-assets/open_in_file_browser.svg'
-import OpenIcon from 'enso-assets/open.svg'
-import PasteIcon from 'enso-assets/paste.svg'
-import PenIcon from 'enso-assets/pen.svg'
-import PeopleIcon from 'enso-assets/people.svg'
-import Play2Icon from 'enso-assets/play2.svg'
-import ScissorsIcon from 'enso-assets/scissors.svg'
-import SettingsIcon from 'enso-assets/settings.svg'
-import SignInIcon from 'enso-assets/sign_in.svg'
-import SignOutIcon from 'enso-assets/sign_out.svg'
-import TagIcon from 'enso-assets/tag.svg'
-import TrashIcon from 'enso-assets/trash.svg'
-import UntrashIcon from 'enso-assets/untrash.svg'
import * as detect from 'enso-common/src/detect'
+import AddDatalinkIcon from '#/assets/add_datalink.svg'
+import AddFolderIcon from '#/assets/add_folder.svg'
+import AddKeyIcon from '#/assets/add_key.svg'
+import AddNetworkIcon from '#/assets/add_network.svg'
+import AppDownloadIcon from '#/assets/app_download.svg'
+import ArrowLeftIcon from '#/assets/arrow_left.svg'
+import ArrowRightIcon from '#/assets/arrow_right.svg'
+import CameraIcon from '#/assets/camera.svg'
+import CloseIcon from '#/assets/close.svg'
+import CloudToIcon from '#/assets/cloud_to.svg'
+import CopyAsPathIcon from '#/assets/copy_as_path.svg'
+import CopyIcon from '#/assets/copy.svg'
+import DataDownloadIcon from '#/assets/data_download.svg'
+import DataUploadIcon from '#/assets/data_upload.svg'
+import DuplicateIcon from '#/assets/duplicate.svg'
+import LogoIcon from '#/assets/enso_logo.svg'
+import OpenInFileBrowserIcon from '#/assets/open_in_file_browser.svg'
+import OpenIcon from '#/assets/open.svg'
+import PasteIcon from '#/assets/paste.svg'
+import PenIcon from '#/assets/pen.svg'
+import PeopleIcon from '#/assets/people.svg'
+import Play2Icon from '#/assets/play2.svg'
+import ScissorsIcon from '#/assets/scissors.svg'
+import SettingsIcon from '#/assets/settings.svg'
+import SignInIcon from '#/assets/sign_in.svg'
+import SignOutIcon from '#/assets/sign_out.svg'
+import TagIcon from '#/assets/tag.svg'
+import TrashIcon from '#/assets/trash.svg'
+import UntrashIcon from '#/assets/untrash.svg'
+
import * as inputBindings from '#/utilities/inputBindings'
export type * from '#/utilities/inputBindings'
diff --git a/app/ide-desktop/lib/dashboard/src/data/__tests__/dataLinkSchema.test.ts b/app/dashboard/src/data/__tests__/dataLinkSchema.test.ts
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/data/__tests__/dataLinkSchema.test.ts
rename to app/dashboard/src/data/__tests__/dataLinkSchema.test.ts
index f48124d46bd..e44ef308b83 100644
--- a/app/ide-desktop/lib/dashboard/src/data/__tests__/dataLinkSchema.test.ts
+++ b/app/dashboard/src/data/__tests__/dataLinkSchema.test.ts
@@ -28,8 +28,8 @@ function testSchema(json: unknown, fileName: string): void {
}
}
-// We need to go up from `app/ide-desktop/lib/dashboard/` to the root of the repo
-const DIR_DEPTH = 7
+// We need to go up from `app/dashboard/` to the root of the repo
+const DIR_DEPTH = 5
const REPO_ROOT = url.fileURLToPath(new URL('../'.repeat(DIR_DEPTH), import.meta.url))
const BASE_DATA_LINKS_ROOT = path.resolve(REPO_ROOT, 'test/Base_Tests/data/datalinks/')
const S3_DATA_LINKS_ROOT = path.resolve(REPO_ROOT, 'test/AWS_Tests/data/')
diff --git a/app/ide-desktop/lib/dashboard/src/data/datalinkSchema.json b/app/dashboard/src/data/datalinkSchema.json
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/data/datalinkSchema.json
rename to app/dashboard/src/data/datalinkSchema.json
diff --git a/app/ide-desktop/lib/dashboard/src/data/datalinkValidator.ts b/app/dashboard/src/data/datalinkValidator.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/data/datalinkValidator.ts
rename to app/dashboard/src/data/datalinkValidator.ts
diff --git a/app/ide-desktop/lib/dashboard/src/data/mimeTypes.ts b/app/dashboard/src/data/mimeTypes.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/data/mimeTypes.ts
rename to app/dashboard/src/data/mimeTypes.ts
diff --git a/app/ide-desktop/lib/dashboard/src/entrypoint.ts b/app/dashboard/src/entrypoint.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/entrypoint.ts
rename to app/dashboard/src/entrypoint.ts
diff --git a/app/ide-desktop/lib/dashboard/src/events/AssetEventType.ts b/app/dashboard/src/events/AssetEventType.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/events/AssetEventType.ts
rename to app/dashboard/src/events/AssetEventType.ts
diff --git a/app/ide-desktop/lib/dashboard/src/events/AssetListEventType.ts b/app/dashboard/src/events/AssetListEventType.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/events/AssetListEventType.ts
rename to app/dashboard/src/events/AssetListEventType.ts
diff --git a/app/ide-desktop/lib/dashboard/src/events/assetEvent.ts b/app/dashboard/src/events/assetEvent.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/events/assetEvent.ts
rename to app/dashboard/src/events/assetEvent.ts
diff --git a/app/ide-desktop/lib/dashboard/src/events/assetListEvent.ts b/app/dashboard/src/events/assetListEvent.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/events/assetListEvent.ts
rename to app/dashboard/src/events/assetListEvent.ts
diff --git a/app/dashboard/src/globals.d.ts b/app/dashboard/src/globals.d.ts
new file mode 100644
index 00000000000..696b23a2e30
--- /dev/null
+++ b/app/dashboard/src/globals.d.ts
@@ -0,0 +1,217 @@
+/** @file Globals defined outside of TypeScript files.
+ * These are from variables defined at build time, environment variables,
+ * monkeypatching on `window` and generated code. */
+///
+import type * as saveAccessToken from '#/utilities/accessToken'
+
+// This file is being imported for its types.
+// prettier-ignore
+// eslint-disable-next-line no-restricted-syntax, @typescript-eslint/consistent-type-imports
+import * as buildJson from './../../build.json' with { type: 'json' };
+
+// =============
+// === Types ===
+// =============
+
+/** Nested configuration options with `string` values. */
+interface StringConfig {
+ [key: string]: StringConfig | string
+}
+
+/** The public interface exposed to `window` by the IDE. */
+interface Enso {
+ readonly main: (inputConfig?: StringConfig) => Promise
+}
+
+// ===================
+// === Backend API ===
+// ===================
+
+/** `window.backendApi` is a context bridge to the main process, when we're running in an
+ * Electron context. It contains non-authentication-related functionality. */
+interface BackendApi {
+ /** Return the ID of the new project. */
+ readonly importProjectFromPath: (
+ openedPath: string,
+ directory: string | null,
+ name: string
+ ) => Promise
+}
+
+// ==========================
+// === Authentication API ===
+// ==========================
+
+/** `window.authenticationApi` is a context bridge to the main process, when we're running in an
+ * Electron context.
+ *
+ * # Safety
+ *
+ * We're assuming that the main process has exposed the `authenticationApi` context bridge (see
+ * `lib/client/src/preload.ts` for details), and that it contains the functions defined in this
+ * interface. Our app can't function if these assumptions are not met, so we're disabling the
+ * TypeScript checks for this interface when we use it. */
+interface AuthenticationApi {
+ /** Open a URL in the system browser. */
+ readonly openUrlInSystemBrowser: (url: string) => void
+ /** Set the callback to be called when the system browser redirects back to a URL in the app,
+ * via a deep link. See `setDeepLinkHandler` for details. */
+ readonly setDeepLinkHandler: (callback: (url: string) => void) => void
+ /** Saves the access token to a file. */
+ readonly saveAccessToken: (accessToken: saveAccessToken.AccessToken | null) => void
+}
+
+// ======================
+// === Navigation API ===
+// ======================
+
+/** `window.navigationApi` is a context bridge to the main process, when we're running in an
+ * Electron context. It contains navigation-related functionality. */
+interface NavigationApi {
+ /** Go back in the navigation history. */
+ readonly goBack: () => void
+ /** Go forward in the navigation history. */
+ readonly goForward: () => void
+}
+
+// ================
+// === Menu API ===
+// ================
+
+/** `window.menuApi` exposes functionality related to the system menu. */
+interface MenuApi {
+ /** Set the callback to be called when the "about" entry is clicked in the "help" menu. */
+ readonly setShowAboutModalHandler: (callback: () => void) => void
+}
+
+// ==================
+// === System API ===
+// ==================
+
+/** `window.systemApi` exposes functionality related to the operating system. */
+interface SystemApi {
+ readonly downloadURL: (url: string, headers?: Record) => void
+ readonly showItemInFolder: (fullPath: string) => void
+}
+
+// ==============================
+// === Project Management API ===
+// ==============================
+
+/** Metadata for a newly imported project. */
+interface ProjectInfo {
+ readonly id: string
+ readonly name: string
+ readonly parentDirectory: string
+}
+
+/** `window.projectManagementApi` exposes functionality related to system events related to
+ * project management. */
+interface ProjectManagementApi {
+ readonly setOpenProjectHandler: (handler: (projectInfo: ProjectInfo) => void) => void
+}
+
+// ====================
+// === Version Info ===
+// ====================
+
+/** Versions of the app, and selected software bundled with Electron. */
+interface VersionInfo {
+ readonly version: string
+ readonly build: string
+ readonly electron: string
+ readonly chrome: string
+}
+
+// =====================================
+// === Global namespace augmentation ===
+// =====================================
+
+// JSDocs here are intentionally empty as these interfaces originate from elsewhere.
+declare global {
+ // Documentation is already inherited.
+ /** */
+ // eslint-disable-next-line no-restricted-syntax
+ interface Window {
+ readonly backendApi?: BackendApi
+ readonly authenticationApi: AuthenticationApi
+ readonly navigationApi: NavigationApi
+ readonly menuApi: MenuApi
+ readonly systemApi?: SystemApi
+ readonly projectManagementApi?: ProjectManagementApi
+ readonly versionInfo?: VersionInfo
+ toggleDevtools: () => void
+ }
+
+ namespace NodeJS {
+ /** Environment variables. */
+ // `TZ` MUST NOT be `readonly`, or else `@types/node` will error.
+ // eslint-disable-next-line no-restricted-syntax
+ interface ProcessEnv {
+ readonly [key: string]: never
+
+ // These are environment variables, and MUST be in CONSTANT_CASE.
+ /* eslint-disable @typescript-eslint/naming-convention */
+ // This is declared in `@types/node`. It MUST be re-declared here to suppress the error
+ // about this property conflicting with the index signature above.
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ TZ?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly CI?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly PROD?: string
+
+ // === Cloud environment variables ===
+
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_REDIRECT?: string
+ // When unset, the `.env` loader tries to load `.env` rather than `..env`.
+ // Set to the empty string to load `.env`.
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_ENVIRONMENT: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_API_URL?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_CHAT_URL?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_SENTRY_DSN?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_STRIPE_KEY?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_COGNITO_USER_POOL_ID?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_COGNITO_USER_POOL_WEB_CLIENT_ID?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_COGNITO_DOMAIN?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_COGNITO_REGION?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_GOOGLE_ANALYTICS_TAG?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_DASHBOARD_VERSION?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_DASHBOARD_COMMIT_HASH?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ENSO_CLOUD_ENSO_HOST?: string
+
+ // === E2E test variables ===
+ readonly PWDEBUG?: '1'
+ readonly IS_IN_PLAYWRIGHT_TEST?: `${boolean}`
+
+ // === Electron watch script variables ===
+
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly ELECTRON_DEV_MODE?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly GUI_CONFIG_PATH?: string
+ // @ts-expect-error The index signature is intentional to disallow unknown env vars.
+ readonly NODE_MODULES_PATH?: string
+ /* eslint-enable @typescript-eslint/naming-convention */
+ }
+ }
+
+ // These are used in other files (because they're globals)
+ /* eslint-disable @typescript-eslint/naming-convention */
+ const BUILD_INFO: buildJson.BuildInfo
+ const PROJECT_MANAGER_IN_BUNDLE_PATH: StringConstructor
+}
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/README.md b/app/dashboard/src/hooks/README.md
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/README.md
rename to app/dashboard/src/hooks/README.md
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/animationHooks.ts b/app/dashboard/src/hooks/animationHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/animationHooks.ts
rename to app/dashboard/src/hooks/animationHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/backendHooks.ts b/app/dashboard/src/hooks/backendHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/backendHooks.ts
rename to app/dashboard/src/hooks/backendHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/billing/FeaturesConfiguration.ts b/app/dashboard/src/hooks/billing/FeaturesConfiguration.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/billing/FeaturesConfiguration.ts
rename to app/dashboard/src/hooks/billing/FeaturesConfiguration.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/billing/index.ts b/app/dashboard/src/hooks/billing/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/billing/index.ts
rename to app/dashboard/src/hooks/billing/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/billing/paywallFeaturesHooks.ts b/app/dashboard/src/hooks/billing/paywallFeaturesHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/billing/paywallFeaturesHooks.ts
rename to app/dashboard/src/hooks/billing/paywallFeaturesHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/billing/paywallHooks.ts b/app/dashboard/src/hooks/billing/paywallHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/billing/paywallHooks.ts
rename to app/dashboard/src/hooks/billing/paywallHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/contextMenuHooks.tsx b/app/dashboard/src/hooks/contextMenuHooks.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/contextMenuHooks.tsx
rename to app/dashboard/src/hooks/contextMenuHooks.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/copyHooks.ts b/app/dashboard/src/hooks/copyHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/copyHooks.ts
rename to app/dashboard/src/hooks/copyHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/debounceCallbackHooks.ts b/app/dashboard/src/hooks/debounceCallbackHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/debounceCallbackHooks.ts
rename to app/dashboard/src/hooks/debounceCallbackHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/debounceStateHooks.ts b/app/dashboard/src/hooks/debounceStateHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/debounceStateHooks.ts
rename to app/dashboard/src/hooks/debounceStateHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/debounceValueHooks.ts b/app/dashboard/src/hooks/debounceValueHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/debounceValueHooks.ts
rename to app/dashboard/src/hooks/debounceValueHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/debugHooks.ts b/app/dashboard/src/hooks/debugHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/debugHooks.ts
rename to app/dashboard/src/hooks/debugHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/dragAndDropHooks.ts b/app/dashboard/src/hooks/dragAndDropHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/dragAndDropHooks.ts
rename to app/dashboard/src/hooks/dragAndDropHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/eventCallbackHooks.ts b/app/dashboard/src/hooks/eventCallbackHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/eventCallbackHooks.ts
rename to app/dashboard/src/hooks/eventCallbackHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/focusHooks.ts b/app/dashboard/src/hooks/focusHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/focusHooks.ts
rename to app/dashboard/src/hooks/focusHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/gtagHooks.ts b/app/dashboard/src/hooks/gtagHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/gtagHooks.ts
rename to app/dashboard/src/hooks/gtagHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/intersectionHooks.ts b/app/dashboard/src/hooks/intersectionHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/intersectionHooks.ts
rename to app/dashboard/src/hooks/intersectionHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/offlineHooks.ts b/app/dashboard/src/hooks/offlineHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/offlineHooks.ts
rename to app/dashboard/src/hooks/offlineHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/projectHooks.ts b/app/dashboard/src/hooks/projectHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/projectHooks.ts
rename to app/dashboard/src/hooks/projectHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/refreshHooks.ts b/app/dashboard/src/hooks/refreshHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/refreshHooks.ts
rename to app/dashboard/src/hooks/refreshHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/scrollHooks.ts b/app/dashboard/src/hooks/scrollHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/scrollHooks.ts
rename to app/dashboard/src/hooks/scrollHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/searchParamsStateHooks.ts b/app/dashboard/src/hooks/searchParamsStateHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/searchParamsStateHooks.ts
rename to app/dashboard/src/hooks/searchParamsStateHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/setAssetHooks.ts b/app/dashboard/src/hooks/setAssetHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/setAssetHooks.ts
rename to app/dashboard/src/hooks/setAssetHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/syncRefHooks.ts b/app/dashboard/src/hooks/syncRefHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/syncRefHooks.ts
rename to app/dashboard/src/hooks/syncRefHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/toastAndLogHooks.ts b/app/dashboard/src/hooks/toastAndLogHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/toastAndLogHooks.ts
rename to app/dashboard/src/hooks/toastAndLogHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/tooltipHooks.ts b/app/dashboard/src/hooks/tooltipHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/tooltipHooks.ts
rename to app/dashboard/src/hooks/tooltipHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/unmountHooks.ts b/app/dashboard/src/hooks/unmountHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/unmountHooks.ts
rename to app/dashboard/src/hooks/unmountHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/useLazyMemoHooks.ts b/app/dashboard/src/hooks/useLazyMemoHooks.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/useLazyMemoHooks.ts
rename to app/dashboard/src/hooks/useLazyMemoHooks.ts
diff --git a/app/ide-desktop/lib/dashboard/src/hooks/useOnScroll.ts b/app/dashboard/src/hooks/useOnScroll.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/hooks/useOnScroll.ts
rename to app/dashboard/src/hooks/useOnScroll.ts
diff --git a/app/ide-desktop/lib/dashboard/src/index.tsx b/app/dashboard/src/index.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/index.tsx
rename to app/dashboard/src/index.tsx
index fe22368c8f8..1c1b7eb8d6c 100644
--- a/app/ide-desktop/lib/dashboard/src/index.tsx
+++ b/app/dashboard/src/index.tsx
@@ -22,6 +22,10 @@ import * as suspense from '#/components/Suspense'
import HttpClient from '#/utilities/HttpClient'
+export type { AccessToken } from '#/utilities/accessToken'
+
+export type { GraphEditorRunner } from '#/layouts/Editor'
+
// =================
// === Constants ===
// =================
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetContextMenu.tsx b/app/dashboard/src/layouts/AssetContextMenu.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetContextMenu.tsx
rename to app/dashboard/src/layouts/AssetContextMenu.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetDiffView/AssetDiffView.tsx b/app/dashboard/src/layouts/AssetDiffView/AssetDiffView.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetDiffView/AssetDiffView.tsx
rename to app/dashboard/src/layouts/AssetDiffView/AssetDiffView.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetDiffView/index.ts b/app/dashboard/src/layouts/AssetDiffView/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetDiffView/index.ts
rename to app/dashboard/src/layouts/AssetDiffView/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetDiffView/useFetchVersionContent.ts b/app/dashboard/src/layouts/AssetDiffView/useFetchVersionContent.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetDiffView/useFetchVersionContent.ts
rename to app/dashboard/src/layouts/AssetDiffView/useFetchVersionContent.ts
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetPanel.tsx b/app/dashboard/src/layouts/AssetPanel.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetPanel.tsx
rename to app/dashboard/src/layouts/AssetPanel.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetProjectSession.tsx b/app/dashboard/src/layouts/AssetProjectSession.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetProjectSession.tsx
rename to app/dashboard/src/layouts/AssetProjectSession.tsx
index edd17e2950c..6279157f963 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/AssetProjectSession.tsx
+++ b/app/dashboard/src/layouts/AssetProjectSession.tsx
@@ -1,7 +1,7 @@
/** @file Displays information describing a specific version of an asset. */
import * as React from 'react'
-import LogsIcon from 'enso-assets/logs.svg'
+import LogsIcon from '#/assets/logs.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetProjectSessions.tsx b/app/dashboard/src/layouts/AssetProjectSessions.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetProjectSessions.tsx
rename to app/dashboard/src/layouts/AssetProjectSessions.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetProperties.tsx b/app/dashboard/src/layouts/AssetProperties.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetProperties.tsx
rename to app/dashboard/src/layouts/AssetProperties.tsx
index 8a4ba5479e5..76d36e41e07 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/AssetProperties.tsx
+++ b/app/dashboard/src/layouts/AssetProperties.tsx
@@ -1,7 +1,7 @@
/** @file Display and modify the properties of an asset. */
import * as React from 'react'
-import PenIcon from 'enso-assets/pen.svg'
+import PenIcon from '#/assets/pen.svg'
import * as datalinkValidator from '#/data/datalinkValidator'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetSearchBar.tsx b/app/dashboard/src/layouts/AssetSearchBar.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetSearchBar.tsx
rename to app/dashboard/src/layouts/AssetSearchBar.tsx
index e2e6bf0d212..6fe65f37281 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/AssetSearchBar.tsx
+++ b/app/dashboard/src/layouts/AssetSearchBar.tsx
@@ -1,9 +1,10 @@
/** @file A search bar containing a text input, and a list of suggestions. */
import * as React from 'react'
-import FindIcon from 'enso-assets/find.svg'
import * as detect from 'enso-common/src/detect'
+import FindIcon from '#/assets/find.svg'
+
import * as backendHooks from '#/hooks/backendHooks'
import * as modalProvider from '#/providers/ModalProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetVersions/AssetVersion.tsx b/app/dashboard/src/layouts/AssetVersions/AssetVersion.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetVersions/AssetVersion.tsx
rename to app/dashboard/src/layouts/AssetVersions/AssetVersion.tsx
index 89988f8bdcd..0b1b70e24fe 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/AssetVersions/AssetVersion.tsx
+++ b/app/dashboard/src/layouts/AssetVersions/AssetVersion.tsx
@@ -1,9 +1,9 @@
/** @file Displays information describing a specific version of an asset. */
import * as React from 'react'
-import CompareIcon from 'enso-assets/compare.svg'
-import DuplicateIcon from 'enso-assets/duplicate.svg'
-import RestoreIcon from 'enso-assets/restore.svg'
+import CompareIcon from '#/assets/compare.svg'
+import DuplicateIcon from '#/assets/duplicate.svg'
+import RestoreIcon from '#/assets/restore.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetVersions/AssetVersions.tsx b/app/dashboard/src/layouts/AssetVersions/AssetVersions.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetVersions/AssetVersions.tsx
rename to app/dashboard/src/layouts/AssetVersions/AssetVersions.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetVersions/useAssetVersions.ts b/app/dashboard/src/layouts/AssetVersions/useAssetVersions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetVersions/useAssetVersions.ts
rename to app/dashboard/src/layouts/AssetVersions/useAssetVersions.ts
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetsTable.tsx b/app/dashboard/src/layouts/AssetsTable.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetsTable.tsx
rename to app/dashboard/src/layouts/AssetsTable.tsx
index c52d7efa8eb..f21b1921e1f 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/AssetsTable.tsx
+++ b/app/dashboard/src/layouts/AssetsTable.tsx
@@ -4,7 +4,7 @@ import * as React from 'react'
import * as reactQuery from '@tanstack/react-query'
import * as toast from 'react-toastify'
-import DropFilesImage from 'enso-assets/drop_files.svg'
+import DropFilesImage from '#/assets/drop_files.svg'
import * as mimeTypes from '#/data/mimeTypes'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetsTable/EventListProvider.tsx b/app/dashboard/src/layouts/AssetsTable/EventListProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetsTable/EventListProvider.tsx
rename to app/dashboard/src/layouts/AssetsTable/EventListProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/AssetsTableContextMenu.tsx b/app/dashboard/src/layouts/AssetsTableContextMenu.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/AssetsTableContextMenu.tsx
rename to app/dashboard/src/layouts/AssetsTableContextMenu.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/CategorySwitcher.tsx b/app/dashboard/src/layouts/CategorySwitcher.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/CategorySwitcher.tsx
rename to app/dashboard/src/layouts/CategorySwitcher.tsx
index 0506646569b..5cf31257e93 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/CategorySwitcher.tsx
+++ b/app/dashboard/src/layouts/CategorySwitcher.tsx
@@ -1,12 +1,13 @@
/** @file Switcher to choose the currently visible assets table category. */
import * as React from 'react'
-import CloudIcon from 'enso-assets/cloud.svg'
-import ComputerIcon from 'enso-assets/computer.svg'
-import RecentIcon from 'enso-assets/recent.svg'
-import Trash2Icon from 'enso-assets/trash2.svg'
import type * as text from 'enso-common/src/text'
+import CloudIcon from '#/assets/cloud.svg'
+import ComputerIcon from '#/assets/computer.svg'
+import RecentIcon from '#/assets/recent.svg'
+import Trash2Icon from '#/assets/trash2.svg'
+
import * as mimeTypes from '#/data/mimeTypes'
import * as offlineHooks from '#/hooks/offlineHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/CategorySwitcher/Category.ts b/app/dashboard/src/layouts/CategorySwitcher/Category.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/CategorySwitcher/Category.ts
rename to app/dashboard/src/layouts/CategorySwitcher/Category.ts
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Chat.tsx b/app/dashboard/src/layouts/Chat.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/layouts/Chat.tsx
rename to app/dashboard/src/layouts/Chat.tsx
index 74ecd0e9f82..53a608b6a8c 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Chat.tsx
+++ b/app/dashboard/src/layouts/Chat.tsx
@@ -3,11 +3,12 @@ import * as React from 'react'
import * as reactDom from 'react-dom'
-import CloseLargeIcon from 'enso-assets/close_large.svg'
-import DefaultUserIcon from 'enso-assets/default_user.svg'
-import FolderArrowIcon from 'enso-assets/folder_arrow.svg'
import * as chat from 'enso-chat/chat'
+import CloseLargeIcon from '#/assets/close_large.svg'
+import DefaultUserIcon from '#/assets/default_user.svg'
+import FolderArrowIcon from '#/assets/folder_arrow.svg'
+
import * as gtagHooks from '#/hooks/gtagHooks'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/ChatPlaceholder.tsx b/app/dashboard/src/layouts/ChatPlaceholder.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/ChatPlaceholder.tsx
rename to app/dashboard/src/layouts/ChatPlaceholder.tsx
index 27ff743738c..7603e343461 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/ChatPlaceholder.tsx
+++ b/app/dashboard/src/layouts/ChatPlaceholder.tsx
@@ -4,7 +4,7 @@ import * as React from 'react'
import * as reactDom from 'react-dom'
import * as router from 'react-router-dom'
-import CloseLargeIcon from 'enso-assets/close_large.svg'
+import CloseLargeIcon from '#/assets/close_large.svg'
import * as appUtils from '#/appUtils'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Drive.tsx b/app/dashboard/src/layouts/Drive.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Drive.tsx
rename to app/dashboard/src/layouts/Drive.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/DriveBar.tsx b/app/dashboard/src/layouts/DriveBar.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/layouts/DriveBar.tsx
rename to app/dashboard/src/layouts/DriveBar.tsx
index 1a9590c2160..89de34bdd6a 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/DriveBar.tsx
+++ b/app/dashboard/src/layouts/DriveBar.tsx
@@ -2,12 +2,12 @@
* the current directory and some configuration options. */
import * as React from 'react'
-import AddDatalinkIcon from 'enso-assets/add_datalink.svg'
-import AddFolderIcon from 'enso-assets/add_folder.svg'
-import AddKeyIcon from 'enso-assets/add_key.svg'
-import DataDownloadIcon from 'enso-assets/data_download.svg'
-import DataUploadIcon from 'enso-assets/data_upload.svg'
-import RightPanelIcon from 'enso-assets/right_panel.svg'
+import AddDatalinkIcon from '#/assets/add_datalink.svg'
+import AddFolderIcon from '#/assets/add_folder.svg'
+import AddKeyIcon from '#/assets/add_key.svg'
+import DataDownloadIcon from '#/assets/data_download.svg'
+import DataUploadIcon from '#/assets/data_upload.svg'
+import RightPanelIcon from '#/assets/right_panel.svg'
import * as offlineHooks from '#/hooks/offlineHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Editor.tsx b/app/dashboard/src/layouts/Editor.tsx
similarity index 83%
rename from app/ide-desktop/lib/dashboard/src/layouts/Editor.tsx
rename to app/dashboard/src/layouts/Editor.tsx
index 7067d40051c..6bd319bf141 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Editor.tsx
+++ b/app/dashboard/src/layouts/Editor.tsx
@@ -3,8 +3,6 @@ import * as React from 'react'
import * as reactQuery from '@tanstack/react-query'
-import type * as types from 'enso-common/src/types'
-
import * as appUtils from '#/appUtils'
import * as gtagHooks from '#/hooks/gtagHooks'
@@ -17,9 +15,42 @@ import * as errorBoundary from '#/components/ErrorBoundary'
import * as suspense from '#/components/Suspense'
import * as backendModule from '#/services/Backend'
+import type Backend from '#/services/Backend'
import * as twMerge from '#/utilities/tailwindMerge'
+// ====================
+// === StringConfig ===
+// ====================
+
+/** A configuration in which values may be strings or nested configurations. */
+interface StringConfig {
+ readonly [key: string]: StringConfig | string
+}
+
+// ========================
+// === GraphEditorProps ===
+// ========================
+
+/** Props for the GUI editor root component. */
+export interface GraphEditorProps {
+ readonly config: StringConfig | null
+ readonly projectId: string
+ readonly hidden: boolean
+ readonly ignoreParamsRegex?: RegExp
+ readonly logEvent: (message: string, projectId?: string | null, metadata?: object | null) => void
+ readonly renameProject: (newName: string) => void
+ readonly backend: Backend | null
+}
+
+// =========================
+// === GraphEditorRunner ===
+// =========================
+
+/** The value passed from the entrypoint to the dashboard, which enables the dashboard to
+ * open a new IDE instance. */
+export type GraphEditorRunner = React.ComponentType
+
// =================
// === Constants ===
// =================
@@ -39,7 +70,7 @@ export interface EditorProps {
readonly project: projectHooks.Project
readonly hidden: boolean
readonly ydocUrl: string | null
- readonly appRunner: types.EditorRunner | null
+ readonly appRunner: GraphEditorRunner | null
readonly renameProject: (newName: string) => void
readonly projectId: backendModule.ProjectAsset['id']
}
@@ -154,7 +185,7 @@ function EditorInternal(props: EditorInternalProps) {
}
}, [hidden, gtagEvent])
- const appProps: types.EditorProps | null = React.useMemo(() => {
+ const appProps = React.useMemo(() => {
const jsonAddress = openedProject.jsonAddress
const binaryAddress = openedProject.binaryAddress
const ydocAddress = ydocUrl ?? ''
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/GlobalContextMenu.tsx b/app/dashboard/src/layouts/GlobalContextMenu.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/GlobalContextMenu.tsx
rename to app/dashboard/src/layouts/GlobalContextMenu.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/InfoBar.tsx b/app/dashboard/src/layouts/InfoBar.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/layouts/InfoBar.tsx
rename to app/dashboard/src/layouts/InfoBar.tsx
index 29fec0dcbfa..3300111ddc6 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/InfoBar.tsx
+++ b/app/dashboard/src/layouts/InfoBar.tsx
@@ -1,8 +1,8 @@
/** @file A toolbar containing chat and the user menu. */
import * as React from 'react'
-import ChatIcon from 'enso-assets/chat.svg'
-import LogoIcon from 'enso-assets/enso_logo.svg'
+import ChatIcon from '#/assets/chat.svg'
+import LogoIcon from '#/assets/enso_logo.svg'
import * as modalProvider from '#/providers/ModalProvider'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/InfoMenu.tsx b/app/dashboard/src/layouts/InfoMenu.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/InfoMenu.tsx
rename to app/dashboard/src/layouts/InfoMenu.tsx
index 52e11c5dcc4..064bd7ffb8b 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/InfoMenu.tsx
+++ b/app/dashboard/src/layouts/InfoMenu.tsx
@@ -1,9 +1,10 @@
/** @file A menu containing info about the app. */
import * as React from 'react'
-import LogoIcon from 'enso-assets/enso_logo.svg'
import * as common from 'enso-common'
+import LogoIcon from '#/assets/enso_logo.svg'
+
import * as authProvider from '#/providers/AuthProvider'
import * as modalProvider from '#/providers/ModalProvider'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Labels.tsx b/app/dashboard/src/layouts/Labels.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/Labels.tsx
rename to app/dashboard/src/layouts/Labels.tsx
index bc9eb981af6..a1b2e1e7a38 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Labels.tsx
+++ b/app/dashboard/src/layouts/Labels.tsx
@@ -1,8 +1,8 @@
/** @file A list of selectable labels. */
import * as React from 'react'
-import PlusIcon from 'enso-assets/plus.svg'
-import Trash2Icon from 'enso-assets/trash2.svg'
+import PlusIcon from '#/assets/plus.svg'
+import Trash2Icon from '#/assets/trash2.svg'
import * as backendHooks from '#/hooks/backendHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/OpenAppWatcher.tsx b/app/dashboard/src/layouts/OpenAppWatcher.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/OpenAppWatcher.tsx
rename to app/dashboard/src/layouts/OpenAppWatcher.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/README.md b/app/dashboard/src/layouts/README.md
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/README.md
rename to app/dashboard/src/layouts/README.md
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Samples.tsx b/app/dashboard/src/layouts/Samples.tsx
similarity index 95%
rename from app/ide-desktop/lib/dashboard/src/layouts/Samples.tsx
rename to app/dashboard/src/layouts/Samples.tsx
index e0008b6b2cc..619d51d2769 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Samples.tsx
+++ b/app/dashboard/src/layouts/Samples.tsx
@@ -1,12 +1,12 @@
/** @file Renders the list of templates from which a project can be created. */
import * as React from 'react'
-import Logo from 'enso-assets/enso_logo.svg'
-import GeoImage from 'enso-assets/geo.svg'
-import HeartIcon from 'enso-assets/heart.svg'
-import OpenCountIcon from 'enso-assets/open_count.svg'
-import SpreadsheetsImage from 'enso-assets/spreadsheets.svg'
-import VisualizeImage from 'enso-assets/visualize.png'
+import Logo from '#/assets/enso_logo.svg'
+import GeoImage from '#/assets/geo.svg'
+import HeartIcon from '#/assets/heart.svg'
+import OpenCountIcon from '#/assets/open_count.svg'
+import SpreadsheetsImage from '#/assets/spreadsheets.svg'
+import VisualizeImage from '#/assets/visualize.png'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/SearchBar.tsx b/app/dashboard/src/layouts/SearchBar.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/SearchBar.tsx
rename to app/dashboard/src/layouts/SearchBar.tsx
index a020b4adea5..06172c0dc6b 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/SearchBar.tsx
+++ b/app/dashboard/src/layouts/SearchBar.tsx
@@ -1,7 +1,7 @@
/** @file A search bar containing a text input, and a list of suggestions. */
import * as React from 'react'
-import FindIcon from 'enso-assets/find.svg'
+import FindIcon from '#/assets/find.svg'
import * as aria from '#/components/aria'
import FocusArea from '#/components/styled/FocusArea'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings.tsx b/app/dashboard/src/layouts/Settings.tsx
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings.tsx
rename to app/dashboard/src/layouts/Settings.tsx
index daf650bfbd6..ab284073d3d 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings.tsx
+++ b/app/dashboard/src/layouts/Settings.tsx
@@ -3,7 +3,7 @@ import * as React from 'react'
import * as reactQuery from '@tanstack/react-query'
-import BurgerMenuIcon from 'enso-assets/burger_menu.svg'
+import BurgerMenuIcon from '#/assets/burger_menu.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as searchParamsState from '#/hooks/searchParamsStateHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/ActivityLogSettingsSection.tsx b/app/dashboard/src/layouts/Settings/ActivityLogSettingsSection.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/ActivityLogSettingsSection.tsx
rename to app/dashboard/src/layouts/Settings/ActivityLogSettingsSection.tsx
index b817f7215f1..9a63f459009 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/ActivityLogSettingsSection.tsx
+++ b/app/dashboard/src/layouts/Settings/ActivityLogSettingsSection.tsx
@@ -1,11 +1,11 @@
/** @file Settings tab for viewing and editing account information. */
import * as React from 'react'
-import DataUploadIcon from 'enso-assets/data_upload.svg'
-import KeyIcon from 'enso-assets/key.svg'
-import Play2Icon from 'enso-assets/play2.svg'
-import SortAscendingIcon from 'enso-assets/sort_ascending.svg'
-import TrashIcon from 'enso-assets/trash.svg'
+import DataUploadIcon from '#/assets/data_upload.svg'
+import KeyIcon from '#/assets/key.svg'
+import Play2Icon from '#/assets/play2.svg'
+import SortAscendingIcon from '#/assets/sort_ascending.svg'
+import TrashIcon from '#/assets/trash.svg'
import * as backendHooks from '#/hooks/backendHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/ChangePasswordForm.tsx b/app/dashboard/src/layouts/Settings/ChangePasswordForm.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/ChangePasswordForm.tsx
rename to app/dashboard/src/layouts/Settings/ChangePasswordForm.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/DeleteUserAccountSettingsSection.tsx b/app/dashboard/src/layouts/Settings/DeleteUserAccountSettingsSection.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/DeleteUserAccountSettingsSection.tsx
rename to app/dashboard/src/layouts/Settings/DeleteUserAccountSettingsSection.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/KeyboardShortcutsSettingsSection.tsx b/app/dashboard/src/layouts/Settings/KeyboardShortcutsSettingsSection.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/KeyboardShortcutsSettingsSection.tsx
rename to app/dashboard/src/layouts/Settings/KeyboardShortcutsSettingsSection.tsx
index ee4be22adac..2fd30f737c8 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/KeyboardShortcutsSettingsSection.tsx
+++ b/app/dashboard/src/layouts/Settings/KeyboardShortcutsSettingsSection.tsx
@@ -1,10 +1,10 @@
/** @file Settings tab for viewing and editing keyboard shortcuts. */
import * as React from 'react'
-import BlankIcon from 'enso-assets/blank.svg'
-import CrossIcon from 'enso-assets/cross.svg'
-import Plus2Icon from 'enso-assets/plus2.svg'
-import ReloadIcon from 'enso-assets/reload.svg'
+import BlankIcon from '#/assets/blank.svg'
+import CrossIcon from '#/assets/cross.svg'
+import Plus2Icon from '#/assets/plus2.svg'
+import ReloadIcon from '#/assets/reload.svg'
import type * as inputBindings from '#/configurations/inputBindings'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/MembersSettingsSection.tsx b/app/dashboard/src/layouts/Settings/MembersSettingsSection.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/MembersSettingsSection.tsx
rename to app/dashboard/src/layouts/Settings/MembersSettingsSection.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/MembersTable.tsx b/app/dashboard/src/layouts/Settings/MembersTable.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/MembersTable.tsx
rename to app/dashboard/src/layouts/Settings/MembersTable.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/OrganizationProfilePictureInput.tsx b/app/dashboard/src/layouts/Settings/OrganizationProfilePictureInput.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/OrganizationProfilePictureInput.tsx
rename to app/dashboard/src/layouts/Settings/OrganizationProfilePictureInput.tsx
index b6dd935564f..93bbeef14b7 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/OrganizationProfilePictureInput.tsx
+++ b/app/dashboard/src/layouts/Settings/OrganizationProfilePictureInput.tsx
@@ -1,7 +1,7 @@
/** @file The input for viewing and changing the organization's profile picture. */
import * as React from 'react'
-import DefaultUserIcon from 'enso-assets/default_user.svg'
+import DefaultUserIcon from '#/assets/default_user.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/ProfilePictureInput.tsx b/app/dashboard/src/layouts/Settings/ProfilePictureInput.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/ProfilePictureInput.tsx
rename to app/dashboard/src/layouts/Settings/ProfilePictureInput.tsx
index cf8094970ec..c7e65848ff5 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/ProfilePictureInput.tsx
+++ b/app/dashboard/src/layouts/Settings/ProfilePictureInput.tsx
@@ -1,7 +1,7 @@
/** @file The input for viewing and changing the user's profile picture. */
import * as React from 'react'
-import DefaultUserIcon from 'enso-assets/default_user.svg'
+import DefaultUserIcon from '#/assets/default_user.svg'
import * as backendHooks from '#/hooks/backendHooks'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsCustomEntry.tsx b/app/dashboard/src/layouts/Settings/SettingsCustomEntry.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsCustomEntry.tsx
rename to app/dashboard/src/layouts/Settings/SettingsCustomEntry.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsEntry.tsx b/app/dashboard/src/layouts/Settings/SettingsEntry.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsEntry.tsx
rename to app/dashboard/src/layouts/Settings/SettingsEntry.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsInputEntry.tsx b/app/dashboard/src/layouts/Settings/SettingsInputEntry.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsInputEntry.tsx
rename to app/dashboard/src/layouts/Settings/SettingsInputEntry.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsPaywall.tsx b/app/dashboard/src/layouts/Settings/SettingsPaywall.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsPaywall.tsx
rename to app/dashboard/src/layouts/Settings/SettingsPaywall.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsSection.tsx b/app/dashboard/src/layouts/Settings/SettingsSection.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsSection.tsx
rename to app/dashboard/src/layouts/Settings/SettingsSection.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsTab.tsx b/app/dashboard/src/layouts/Settings/SettingsTab.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsTab.tsx
rename to app/dashboard/src/layouts/Settings/SettingsTab.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsTabType.ts b/app/dashboard/src/layouts/Settings/SettingsTabType.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/SettingsTabType.ts
rename to app/dashboard/src/layouts/Settings/SettingsTabType.ts
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupRow.tsx b/app/dashboard/src/layouts/Settings/UserGroupRow.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupRow.tsx
rename to app/dashboard/src/layouts/Settings/UserGroupRow.tsx
index c86a1fd8356..420873316e4 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupRow.tsx
+++ b/app/dashboard/src/layouts/Settings/UserGroupRow.tsx
@@ -1,7 +1,7 @@
/** @file A row representing a user group. */
import * as React from 'react'
-import Cross2 from 'enso-assets/cross2.svg'
+import Cross2 from '#/assets/cross2.svg'
import type * as backendHooks from '#/hooks/backendHooks'
import * as contextMenuHooks from '#/hooks/contextMenuHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupUserRow.tsx b/app/dashboard/src/layouts/Settings/UserGroupUserRow.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupUserRow.tsx
rename to app/dashboard/src/layouts/Settings/UserGroupUserRow.tsx
index dbbf5841e53..2553edd9a5f 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupUserRow.tsx
+++ b/app/dashboard/src/layouts/Settings/UserGroupUserRow.tsx
@@ -1,7 +1,7 @@
/** @file A row of the user groups table representing a user. */
import * as React from 'react'
-import Cross2 from 'enso-assets/cross2.svg'
+import Cross2 from '#/assets/cross2.svg'
import type * as backendHooks from '#/hooks/backendHooks'
import * as contextMenuHooks from '#/hooks/contextMenuHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupsSettingsSection.tsx b/app/dashboard/src/layouts/Settings/UserGroupsSettingsSection.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/UserGroupsSettingsSection.tsx
rename to app/dashboard/src/layouts/Settings/UserGroupsSettingsSection.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/UserRow.tsx b/app/dashboard/src/layouts/Settings/UserRow.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/UserRow.tsx
rename to app/dashboard/src/layouts/Settings/UserRow.tsx
index 2c32992c56b..9793b38bd6f 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/UserRow.tsx
+++ b/app/dashboard/src/layouts/Settings/UserRow.tsx
@@ -1,7 +1,7 @@
/** @file A row representing a user in a table of users. */
import * as React from 'react'
-import Cross2 from 'enso-assets/cross2.svg'
+import Cross2 from '#/assets/cross2.svg'
import * as contextMenuHooks from '#/hooks/contextMenuHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/Settings/settingsData.tsx b/app/dashboard/src/layouts/Settings/settingsData.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/layouts/Settings/settingsData.tsx
rename to app/dashboard/src/layouts/Settings/settingsData.tsx
index 7017437c922..f3f78b5ffd3 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/Settings/settingsData.tsx
+++ b/app/dashboard/src/layouts/Settings/settingsData.tsx
@@ -3,14 +3,15 @@ import * as React from 'react'
import isEmail from 'validator/lib/isEmail'
-import ComputerIcon from 'enso-assets/computer.svg'
-import KeyboardShortcutsIcon from 'enso-assets/keyboard_shortcuts.svg'
-import LogIcon from 'enso-assets/log.svg'
-import PeopleSettingsIcon from 'enso-assets/people_settings.svg'
-import PeopleIcon from 'enso-assets/people.svg'
-import SettingsIcon from 'enso-assets/settings.svg'
import type * as text from 'enso-common/src/text'
+import ComputerIcon from '#/assets/computer.svg'
+import KeyboardShortcutsIcon from '#/assets/keyboard_shortcuts.svg'
+import LogIcon from '#/assets/log.svg'
+import PeopleSettingsIcon from '#/assets/people_settings.svg'
+import PeopleIcon from '#/assets/people.svg'
+import SettingsIcon from '#/assets/settings.svg'
+
import * as inputBindings from '#/configurations/inputBindings'
import type * as billing from '#/hooks/billing'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/SettingsSidebar.tsx b/app/dashboard/src/layouts/SettingsSidebar.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/SettingsSidebar.tsx
rename to app/dashboard/src/layouts/SettingsSidebar.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/StartModal.tsx b/app/dashboard/src/layouts/StartModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/StartModal.tsx
rename to app/dashboard/src/layouts/StartModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/TabBar.tsx b/app/dashboard/src/layouts/TabBar.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/layouts/TabBar.tsx
rename to app/dashboard/src/layouts/TabBar.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/UserBar.tsx b/app/dashboard/src/layouts/UserBar.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/layouts/UserBar.tsx
rename to app/dashboard/src/layouts/UserBar.tsx
index b246b5d9f4a..2ded4e37a7a 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/UserBar.tsx
+++ b/app/dashboard/src/layouts/UserBar.tsx
@@ -1,8 +1,8 @@
/** @file A toolbar containing chat and the user menu. */
import * as React from 'react'
-import ChatIcon from 'enso-assets/chat.svg'
-import DefaultUserIcon from 'enso-assets/default_user.svg'
+import ChatIcon from '#/assets/chat.svg'
+import DefaultUserIcon from '#/assets/default_user.svg'
import * as appUtils from '#/appUtils'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/UserMenu.tsx b/app/dashboard/src/layouts/UserMenu.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/layouts/UserMenu.tsx
rename to app/dashboard/src/layouts/UserMenu.tsx
index 4e1bedd95a8..11b8db9e29e 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/UserMenu.tsx
+++ b/app/dashboard/src/layouts/UserMenu.tsx
@@ -1,7 +1,7 @@
/** @file The UserMenu component provides a dropdown menu of user actions and settings. */
import * as React from 'react'
-import DefaultUserIcon from 'enso-assets/default_user.svg'
+import DefaultUserIcon from '#/assets/default_user.svg'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/WhatsNew.tsx b/app/dashboard/src/layouts/WhatsNew.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/layouts/WhatsNew.tsx
rename to app/dashboard/src/layouts/WhatsNew.tsx
index 0d3fef62147..320254185d2 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/WhatsNew.tsx
+++ b/app/dashboard/src/layouts/WhatsNew.tsx
@@ -1,9 +1,9 @@
/** @file Community updates for the app. */
import * as React from 'react'
-import DiscordIcon from 'enso-assets/discord.svg'
-import IntegrationsImage from 'enso-assets/integrations.png'
-import YoutubeIcon from 'enso-assets/youtube.svg'
+import DiscordIcon from '#/assets/discord.svg'
+import IntegrationsImage from '#/assets/integrations.png'
+import YoutubeIcon from '#/assets/youtube.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/modals/AboutModal.tsx b/app/dashboard/src/modals/AboutModal.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/modals/AboutModal.tsx
rename to app/dashboard/src/modals/AboutModal.tsx
index 9d4a69e366f..64873fb4a14 100644
--- a/app/ide-desktop/lib/dashboard/src/modals/AboutModal.tsx
+++ b/app/dashboard/src/modals/AboutModal.tsx
@@ -1,9 +1,10 @@
/** @file Modal for confirming delete of any type of asset. */
import * as React from 'react'
-import LogoIcon from 'enso-assets/enso_logo.svg'
import type * as text from 'enso-common/src/text'
+import LogoIcon from '#/assets/enso_logo.svg'
+
import * as backendProvider from '#/providers/BackendProvider'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/modals/AddPaymentMethodModal.tsx b/app/dashboard/src/modals/AddPaymentMethodModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/AddPaymentMethodModal.tsx
rename to app/dashboard/src/modals/AddPaymentMethodModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/CaptureKeyboardShortcutModal.tsx b/app/dashboard/src/modals/CaptureKeyboardShortcutModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/CaptureKeyboardShortcutModal.tsx
rename to app/dashboard/src/modals/CaptureKeyboardShortcutModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/ConfirmDeleteModal.tsx b/app/dashboard/src/modals/ConfirmDeleteModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/ConfirmDeleteModal.tsx
rename to app/dashboard/src/modals/ConfirmDeleteModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/ConfirmDeleteUserModal.tsx b/app/dashboard/src/modals/ConfirmDeleteUserModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/ConfirmDeleteUserModal.tsx
rename to app/dashboard/src/modals/ConfirmDeleteUserModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/DragModal.tsx b/app/dashboard/src/modals/DragModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/DragModal.tsx
rename to app/dashboard/src/modals/DragModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/DuplicateAssetsModal.tsx b/app/dashboard/src/modals/DuplicateAssetsModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/DuplicateAssetsModal.tsx
rename to app/dashboard/src/modals/DuplicateAssetsModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/EditAssetDescriptionModal.tsx b/app/dashboard/src/modals/EditAssetDescriptionModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/EditAssetDescriptionModal.tsx
rename to app/dashboard/src/modals/EditAssetDescriptionModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersForm.tsx b/app/dashboard/src/modals/InviteUsersModal/InviteUsersForm.tsx
similarity index 87%
rename from app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersForm.tsx
rename to app/dashboard/src/modals/InviteUsersModal/InviteUsersForm.tsx
index 35df4e7ca33..5b1a7a4932e 100644
--- a/app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersForm.tsx
+++ b/app/dashboard/src/modals/InviteUsersModal/InviteUsersForm.tsx
@@ -74,33 +74,30 @@ export function InviteUsersForm(props: InviteUsersFormProps) {
const trimValue = value.trim()
const { entries } = getEmailsFromInput(value)
- // We wrap the code in a try-catch block to prevent the app from crashing
- // if the browser does not support the CSS.highlights API.
- // Currently, only Firefox doesn't support it.
- try {
+ if (typeof Highlight !== 'undefined') {
CSS.highlights.delete('field-wrong-email')
+ }
- let offset = 0
+ let offset = 0
- const wrongEmailsRanges: Range[] = []
+ const wrongEmailsRanges: Range[] = []
- for (const entry of entries) {
- const emailIndex = trimValue.indexOf(entry.email, offset)
+ for (const entry of entries) {
+ const emailIndex = trimValue.indexOf(entry.email, offset)
- const range = new Range()
- range.setStart(inputRef.current.firstChild, emailIndex)
- range.setEnd(inputRef.current.firstChild, emailIndex + entry.email.length)
+ const range = new Range()
+ range.setStart(inputRef.current.firstChild, emailIndex)
+ range.setEnd(inputRef.current.firstChild, emailIndex + entry.email.length)
- if (!isEmail(entry.email)) {
- wrongEmailsRanges.push(range)
- }
-
- offset = emailIndex + entry.email.length
+ if (!isEmail(entry.email)) {
+ wrongEmailsRanges.push(range)
}
+ offset = emailIndex + entry.email.length
+ }
+
+ if (typeof Highlight !== 'undefined') {
CSS.highlights.set('field-wrong-email', new Highlight(...wrongEmailsRanges))
- } catch (error) {
- // ignore error
}
}
})
diff --git a/app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersModal.tsx b/app/dashboard/src/modals/InviteUsersModal/InviteUsersModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersModal.tsx
rename to app/dashboard/src/modals/InviteUsersModal/InviteUsersModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersSuccess.tsx b/app/dashboard/src/modals/InviteUsersModal/InviteUsersSuccess.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersSuccess.tsx
rename to app/dashboard/src/modals/InviteUsersModal/InviteUsersSuccess.tsx
index 4cb5545fe6d..e3d6d304c46 100644
--- a/app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/InviteUsersSuccess.tsx
+++ b/app/dashboard/src/modals/InviteUsersModal/InviteUsersSuccess.tsx
@@ -3,7 +3,7 @@ import * as React from 'react'
import * as reactRouterDom from 'react-router-dom'
-import ArrowRightIcon from 'enso-assets/arrow_right.svg'
+import ArrowRightIcon from '#/assets/arrow_right.svg'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/index.ts b/app/dashboard/src/modals/InviteUsersModal/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/InviteUsersModal/index.ts
rename to app/dashboard/src/modals/InviteUsersModal/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/modals/ManageLabelsModal.tsx b/app/dashboard/src/modals/ManageLabelsModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/ManageLabelsModal.tsx
rename to app/dashboard/src/modals/ManageLabelsModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/ManagePermissionsModal.tsx b/app/dashboard/src/modals/ManagePermissionsModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/ManagePermissionsModal.tsx
rename to app/dashboard/src/modals/ManagePermissionsModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/NewLabelModal.tsx b/app/dashboard/src/modals/NewLabelModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/NewLabelModal.tsx
rename to app/dashboard/src/modals/NewLabelModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/NewUserGroupModal.tsx b/app/dashboard/src/modals/NewUserGroupModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/NewUserGroupModal.tsx
rename to app/dashboard/src/modals/NewUserGroupModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/ProjectLogsModal.tsx b/app/dashboard/src/modals/ProjectLogsModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/ProjectLogsModal.tsx
rename to app/dashboard/src/modals/ProjectLogsModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/SetOrganizationNameModal.tsx b/app/dashboard/src/modals/SetOrganizationNameModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/SetOrganizationNameModal.tsx
rename to app/dashboard/src/modals/SetOrganizationNameModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/TermsOfServiceModal.tsx b/app/dashboard/src/modals/TermsOfServiceModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/TermsOfServiceModal.tsx
rename to app/dashboard/src/modals/TermsOfServiceModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/UpsertDatalinkModal.tsx b/app/dashboard/src/modals/UpsertDatalinkModal.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/modals/UpsertDatalinkModal.tsx
rename to app/dashboard/src/modals/UpsertDatalinkModal.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/modals/UpsertSecretModal.tsx b/app/dashboard/src/modals/UpsertSecretModal.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/modals/UpsertSecretModal.tsx
rename to app/dashboard/src/modals/UpsertSecretModal.tsx
index d0e0d2144a6..b256213a56b 100644
--- a/app/ide-desktop/lib/dashboard/src/modals/UpsertSecretModal.tsx
+++ b/app/dashboard/src/modals/UpsertSecretModal.tsx
@@ -1,8 +1,8 @@
/** @file Modal for confirming delete of any type of asset. */
import * as React from 'react'
-import EyeCrossedIcon from 'enso-assets/eye_crossed.svg'
-import EyeIcon from 'enso-assets/eye.svg'
+import EyeCrossedIcon from '#/assets/eye_crossed.svg'
+import EyeIcon from '#/assets/eye.svg'
import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/README.md b/app/dashboard/src/pages/README.md
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/README.md
rename to app/dashboard/src/pages/README.md
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/AuthenticationPage.tsx b/app/dashboard/src/pages/authentication/AuthenticationPage.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/AuthenticationPage.tsx
rename to app/dashboard/src/pages/authentication/AuthenticationPage.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/ConfirmRegistration.tsx b/app/dashboard/src/pages/authentication/ConfirmRegistration.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/ConfirmRegistration.tsx
rename to app/dashboard/src/pages/authentication/ConfirmRegistration.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/ErrorScreen.tsx b/app/dashboard/src/pages/authentication/ErrorScreen.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/ErrorScreen.tsx
rename to app/dashboard/src/pages/authentication/ErrorScreen.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/ForgotPassword.tsx b/app/dashboard/src/pages/authentication/ForgotPassword.tsx
similarity index 92%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/ForgotPassword.tsx
rename to app/dashboard/src/pages/authentication/ForgotPassword.tsx
index db7a03441be..56fc5a672b6 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/authentication/ForgotPassword.tsx
+++ b/app/dashboard/src/pages/authentication/ForgotPassword.tsx
@@ -2,9 +2,9 @@
* flow. */
import * as React from 'react'
-import ArrowRightIcon from 'enso-assets/arrow_right.svg'
-import AtIcon from 'enso-assets/at.svg'
-import GoBackIcon from 'enso-assets/go_back.svg'
+import ArrowRightIcon from '#/assets/arrow_right.svg'
+import AtIcon from '#/assets/at.svg'
+import GoBackIcon from '#/assets/go_back.svg'
import * as appUtils from '#/appUtils'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/LoadingScreen.tsx b/app/dashboard/src/pages/authentication/LoadingScreen.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/LoadingScreen.tsx
rename to app/dashboard/src/pages/authentication/LoadingScreen.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/Login.tsx b/app/dashboard/src/pages/authentication/Login.tsx
similarity index 94%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/Login.tsx
rename to app/dashboard/src/pages/authentication/Login.tsx
index 8e377374863..36210df5717 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/authentication/Login.tsx
+++ b/app/dashboard/src/pages/authentication/Login.tsx
@@ -3,15 +3,16 @@ import * as React from 'react'
import * as router from 'react-router-dom'
-import ArrowRightIcon from 'enso-assets/arrow_right.svg'
-import AtIcon from 'enso-assets/at.svg'
-import CreateAccountIcon from 'enso-assets/create_account.svg'
-import GithubIcon from 'enso-assets/github.svg'
-import GoogleIcon from 'enso-assets/google.svg'
-import LockIcon from 'enso-assets/lock.svg'
import * as common from 'enso-common'
import * as detect from 'enso-common/src/detect'
+import ArrowRightIcon from '#/assets/arrow_right.svg'
+import AtIcon from '#/assets/at.svg'
+import CreateAccountIcon from '#/assets/create_account.svg'
+import GithubIcon from '#/assets/github.svg'
+import GoogleIcon from '#/assets/google.svg'
+import LockIcon from '#/assets/lock.svg'
+
import * as appUtils from '#/appUtils'
import * as authProvider from '#/providers/AuthProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/Registration.tsx b/app/dashboard/src/pages/authentication/Registration.tsx
similarity index 95%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/Registration.tsx
rename to app/dashboard/src/pages/authentication/Registration.tsx
index abd7a82eb04..71c5362304a 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/authentication/Registration.tsx
+++ b/app/dashboard/src/pages/authentication/Registration.tsx
@@ -3,10 +3,10 @@ import * as React from 'react'
import * as router from 'react-router-dom'
-import AtIcon from 'enso-assets/at.svg'
-import CreateAccountIcon from 'enso-assets/create_account.svg'
-import GoBackIcon from 'enso-assets/go_back.svg'
-import LockIcon from 'enso-assets/lock.svg'
+import AtIcon from '#/assets/at.svg'
+import CreateAccountIcon from '#/assets/create_account.svg'
+import GoBackIcon from '#/assets/go_back.svg'
+import LockIcon from '#/assets/lock.svg'
import * as appUtils from '#/appUtils'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/ResetPassword.tsx b/app/dashboard/src/pages/authentication/ResetPassword.tsx
similarity index 96%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/ResetPassword.tsx
rename to app/dashboard/src/pages/authentication/ResetPassword.tsx
index 1202d023adb..fd7d10f5ca8 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/authentication/ResetPassword.tsx
+++ b/app/dashboard/src/pages/authentication/ResetPassword.tsx
@@ -4,9 +4,9 @@ import * as React from 'react'
import * as router from 'react-router-dom'
-import ArrowRightIcon from 'enso-assets/arrow_right.svg'
-import GoBackIcon from 'enso-assets/go_back.svg'
-import LockIcon from 'enso-assets/lock.svg'
+import ArrowRightIcon from '#/assets/arrow_right.svg'
+import GoBackIcon from '#/assets/go_back.svg'
+import LockIcon from '#/assets/lock.svg'
import * as appUtils from '#/appUtils'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/RestoreAccount.tsx b/app/dashboard/src/pages/authentication/RestoreAccount.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/RestoreAccount.tsx
rename to app/dashboard/src/pages/authentication/RestoreAccount.tsx
index 7a7e13f455c..28fc70df321 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/authentication/RestoreAccount.tsx
+++ b/app/dashboard/src/pages/authentication/RestoreAccount.tsx
@@ -3,7 +3,7 @@ import * as React from 'react'
import * as reactQuery from '@tanstack/react-query'
-import UntrashIcon from 'enso-assets/untrash.svg'
+import UntrashIcon from '#/assets/untrash.svg'
import * as authProvider from '#/providers/AuthProvider'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/authentication/SetUsername.tsx b/app/dashboard/src/pages/authentication/SetUsername.tsx
similarity index 94%
rename from app/ide-desktop/lib/dashboard/src/pages/authentication/SetUsername.tsx
rename to app/dashboard/src/pages/authentication/SetUsername.tsx
index 8fc0e15824d..71220e1713f 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/authentication/SetUsername.tsx
+++ b/app/dashboard/src/pages/authentication/SetUsername.tsx
@@ -2,8 +2,8 @@
* registration. */
import * as React from 'react'
-import ArrowRightIcon from 'enso-assets/arrow_right.svg'
-import AtIcon from 'enso-assets/at.svg'
+import ArrowRightIcon from '#/assets/arrow_right.svg'
+import AtIcon from '#/assets/at.svg'
import * as authProvider from '#/providers/AuthProvider'
import * as backendProvider from '#/providers/BackendProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/dashboard/Dashboard.tsx b/app/dashboard/src/pages/dashboard/Dashboard.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/pages/dashboard/Dashboard.tsx
rename to app/dashboard/src/pages/dashboard/Dashboard.tsx
index 293d0c7d990..8433672e3e3 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/dashboard/Dashboard.tsx
+++ b/app/dashboard/src/pages/dashboard/Dashboard.tsx
@@ -5,11 +5,11 @@ import * as React from 'react'
import * as validator from 'validator'
import * as z from 'zod'
-import DriveIcon from 'enso-assets/drive.svg'
-import EditorIcon from 'enso-assets/network.svg'
-import SettingsIcon from 'enso-assets/settings.svg'
import * as detect from 'enso-common/src/detect'
-import type * as types from 'enso-common/src/types'
+
+import DriveIcon from '#/assets/drive.svg'
+import EditorIcon from '#/assets/network.svg'
+import SettingsIcon from '#/assets/settings.svg'
import * as eventCallbacks from '#/hooks/eventCallbackHooks'
import * as projectHooks from '#/hooks/projectHooks'
@@ -32,6 +32,7 @@ import Category, * as categoryModule from '#/layouts/CategorySwitcher/Category'
import Chat from '#/layouts/Chat'
import ChatPlaceholder from '#/layouts/ChatPlaceholder'
import Drive from '#/layouts/Drive'
+import type * as editor from '#/layouts/Editor'
import Editor from '#/layouts/Editor'
import Settings from '#/layouts/Settings'
import * as tabBar from '#/layouts/TabBar'
@@ -72,7 +73,7 @@ LocalStorage.registerKey('isAssetPanelVisible', { schema: z.boolean() })
export interface DashboardProps {
/** Whether the application may have the local backend running. */
readonly supportsLocalBackend: boolean
- readonly appRunner: types.EditorRunner | null
+ readonly appRunner: editor.GraphEditorRunner | null
readonly initialProjectName: string | null
readonly ydocUrl: string | null
}
diff --git a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/Subscribe.tsx b/app/dashboard/src/pages/subscribe/Subscribe/Subscribe.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/Subscribe.tsx
rename to app/dashboard/src/pages/subscribe/Subscribe/Subscribe.tsx
index 71fc4a737fb..d34a023f594 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/Subscribe.tsx
+++ b/app/dashboard/src/pages/subscribe/Subscribe/Subscribe.tsx
@@ -4,7 +4,7 @@ import * as React from 'react'
import * as reactQuery from '@tanstack/react-query'
import * as router from 'react-router-dom'
-import Back from 'enso-assets/arrow_left.svg'
+import Back from '#/assets/arrow_left.svg'
import * as appUtils from '#/appUtils'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/components/Card.tsx b/app/dashboard/src/pages/subscribe/Subscribe/components/Card.tsx
similarity index 97%
rename from app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/components/Card.tsx
rename to app/dashboard/src/pages/subscribe/Subscribe/components/Card.tsx
index 8df72f03d5a..c441032fa4b 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/components/Card.tsx
+++ b/app/dashboard/src/pages/subscribe/Subscribe/components/Card.tsx
@@ -5,9 +5,10 @@
*/
import * as React from 'react'
-import Check from 'enso-assets/check_mark.svg'
import type * as text from 'enso-common/src/text'
+import Check from '#/assets/check_mark.svg'
+
import * as textProvider from '#/providers/TextProvider'
import * as aria from '#/components/aria'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/components/index.ts b/app/dashboard/src/pages/subscribe/Subscribe/components/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/components/index.ts
rename to app/dashboard/src/pages/subscribe/Subscribe/components/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/getComponentForPlan.tsx b/app/dashboard/src/pages/subscribe/Subscribe/getComponentForPlan.tsx
similarity index 98%
rename from app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/getComponentForPlan.tsx
rename to app/dashboard/src/pages/subscribe/Subscribe/getComponentForPlan.tsx
index eb8d810a35d..a8737ba586c 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/getComponentForPlan.tsx
+++ b/app/dashboard/src/pages/subscribe/Subscribe/getComponentForPlan.tsx
@@ -5,9 +5,10 @@
*/
import * as React from 'react'
-import OpenInNewTabIcon from 'enso-assets/open.svg'
import type * as text from 'enso-common/src/text'
+import OpenInNewTabIcon from '#/assets/open.svg'
+
import * as appUtils from '#/appUtils'
import * as textProvider from '#/providers/TextProvider'
diff --git a/app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/index.ts b/app/dashboard/src/pages/subscribe/Subscribe/index.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/subscribe/Subscribe/index.ts
rename to app/dashboard/src/pages/subscribe/Subscribe/index.ts
diff --git a/app/ide-desktop/lib/dashboard/src/pages/subscribe/SubscribeSuccess.tsx b/app/dashboard/src/pages/subscribe/SubscribeSuccess.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/subscribe/SubscribeSuccess.tsx
rename to app/dashboard/src/pages/subscribe/SubscribeSuccess.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/pages/subscribe/constants.ts b/app/dashboard/src/pages/subscribe/constants.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/pages/subscribe/constants.ts
rename to app/dashboard/src/pages/subscribe/constants.ts
diff --git a/app/ide-desktop/lib/dashboard/src/providers/AreaFocusProvider.tsx b/app/dashboard/src/providers/AreaFocusProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/AreaFocusProvider.tsx
rename to app/dashboard/src/providers/AreaFocusProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/AuthProvider.tsx b/app/dashboard/src/providers/AuthProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/AuthProvider.tsx
rename to app/dashboard/src/providers/AuthProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/BackendProvider.tsx b/app/dashboard/src/providers/BackendProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/BackendProvider.tsx
rename to app/dashboard/src/providers/BackendProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/FocusClassProvider.tsx b/app/dashboard/src/providers/FocusClassProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/FocusClassProvider.tsx
rename to app/dashboard/src/providers/FocusClassProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/FocusDirectionProvider.tsx b/app/dashboard/src/providers/FocusDirectionProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/FocusDirectionProvider.tsx
rename to app/dashboard/src/providers/FocusDirectionProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/HttpClientProvider.tsx b/app/dashboard/src/providers/HttpClientProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/HttpClientProvider.tsx
rename to app/dashboard/src/providers/HttpClientProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/InputBindingsProvider.tsx b/app/dashboard/src/providers/InputBindingsProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/InputBindingsProvider.tsx
rename to app/dashboard/src/providers/InputBindingsProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/LocalStorageProvider.tsx b/app/dashboard/src/providers/LocalStorageProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/LocalStorageProvider.tsx
rename to app/dashboard/src/providers/LocalStorageProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/LoggerProvider.tsx b/app/dashboard/src/providers/LoggerProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/LoggerProvider.tsx
rename to app/dashboard/src/providers/LoggerProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/ModalProvider.tsx b/app/dashboard/src/providers/ModalProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/ModalProvider.tsx
rename to app/dashboard/src/providers/ModalProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/Navigator2DProvider.tsx b/app/dashboard/src/providers/Navigator2DProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/Navigator2DProvider.tsx
rename to app/dashboard/src/providers/Navigator2DProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/ProjectsProvider.tsx b/app/dashboard/src/providers/ProjectsProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/ProjectsProvider.tsx
rename to app/dashboard/src/providers/ProjectsProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/SessionProvider.tsx b/app/dashboard/src/providers/SessionProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/SessionProvider.tsx
rename to app/dashboard/src/providers/SessionProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/StripeProvider.tsx b/app/dashboard/src/providers/StripeProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/StripeProvider.tsx
rename to app/dashboard/src/providers/StripeProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/providers/TextProvider.tsx b/app/dashboard/src/providers/TextProvider.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/providers/TextProvider.tsx
rename to app/dashboard/src/providers/TextProvider.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/services/Backend.ts b/app/dashboard/src/services/Backend.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/services/Backend.ts
rename to app/dashboard/src/services/Backend.ts
diff --git a/app/ide-desktop/lib/dashboard/src/services/LocalBackend.ts b/app/dashboard/src/services/LocalBackend.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/services/LocalBackend.ts
rename to app/dashboard/src/services/LocalBackend.ts
diff --git a/app/ide-desktop/lib/dashboard/src/services/ProjectManager.ts b/app/dashboard/src/services/ProjectManager.ts
similarity index 99%
rename from app/ide-desktop/lib/dashboard/src/services/ProjectManager.ts
rename to app/dashboard/src/services/ProjectManager.ts
index d8a9f020622..ac220108671 100644
--- a/app/ide-desktop/lib/dashboard/src/services/ProjectManager.ts
+++ b/app/dashboard/src/services/ProjectManager.ts
@@ -295,6 +295,8 @@ export function getDirectoryAndName(path: Path) {
/** Possible events that may be emitted by a {@link ProjectManager}. */
export enum ProjectManagerEvents {
+ // If this member is renamed, the corresponding event listener should also be renamed in
+ // `app/gui2/src/components/GraphEditor/toasts.ts`.
loadingFailed = 'project-manager-loading-failed',
}
diff --git a/app/ide-desktop/lib/dashboard/src/services/RemoteBackend.ts b/app/dashboard/src/services/RemoteBackend.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/services/RemoteBackend.ts
rename to app/dashboard/src/services/RemoteBackend.ts
diff --git a/app/ide-desktop/lib/dashboard/src/services/remoteBackendPaths.ts b/app/dashboard/src/services/remoteBackendPaths.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/services/remoteBackendPaths.ts
rename to app/dashboard/src/services/remoteBackendPaths.ts
diff --git a/app/ide-desktop/lib/dashboard/src/tailwind.css b/app/dashboard/src/tailwind.css
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/tailwind.css
rename to app/dashboard/src/tailwind.css
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/AssetQuery.ts b/app/dashboard/src/utilities/AssetQuery.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/AssetQuery.ts
rename to app/dashboard/src/utilities/AssetQuery.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/AssetTreeNode.ts b/app/dashboard/src/utilities/AssetTreeNode.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/AssetTreeNode.ts
rename to app/dashboard/src/utilities/AssetTreeNode.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/Debug.tsx b/app/dashboard/src/utilities/Debug.tsx
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/Debug.tsx
rename to app/dashboard/src/utilities/Debug.tsx
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/HttpClient.ts b/app/dashboard/src/utilities/HttpClient.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/HttpClient.ts
rename to app/dashboard/src/utilities/HttpClient.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/LocalStorage.ts b/app/dashboard/src/utilities/LocalStorage.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/LocalStorage.ts
rename to app/dashboard/src/utilities/LocalStorage.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/Navigator2D.ts b/app/dashboard/src/utilities/Navigator2D.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/Navigator2D.ts
rename to app/dashboard/src/utilities/Navigator2D.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/PasteType.ts b/app/dashboard/src/utilities/PasteType.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/PasteType.ts
rename to app/dashboard/src/utilities/PasteType.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/Visibility.ts b/app/dashboard/src/utilities/Visibility.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/Visibility.ts
rename to app/dashboard/src/utilities/Visibility.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/AssetQuery.test.ts b/app/dashboard/src/utilities/__tests__/AssetQuery.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/AssetQuery.test.ts
rename to app/dashboard/src/utilities/__tests__/AssetQuery.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/array.test.ts b/app/dashboard/src/utilities/__tests__/array.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/array.test.ts
rename to app/dashboard/src/utilities/__tests__/array.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/dateTime.test.ts b/app/dashboard/src/utilities/__tests__/dateTime.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/dateTime.test.ts
rename to app/dashboard/src/utilities/__tests__/dateTime.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/error.test.ts b/app/dashboard/src/utilities/__tests__/error.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/error.test.ts
rename to app/dashboard/src/utilities/__tests__/error.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/fileInfo.test.ts b/app/dashboard/src/utilities/__tests__/fileInfo.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/fileInfo.test.ts
rename to app/dashboard/src/utilities/__tests__/fileInfo.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/jsonSchema.test.ts b/app/dashboard/src/utilities/__tests__/jsonSchema.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/jsonSchema.test.ts
rename to app/dashboard/src/utilities/__tests__/jsonSchema.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/parseUserEmails.test.ts b/app/dashboard/src/utilities/__tests__/parseUserEmails.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/parseUserEmails.test.ts
rename to app/dashboard/src/utilities/__tests__/parseUserEmails.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/set.test.ts b/app/dashboard/src/utilities/__tests__/set.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/set.test.ts
rename to app/dashboard/src/utilities/__tests__/set.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/shortcuts.test.ts b/app/dashboard/src/utilities/__tests__/shortcuts.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/shortcuts.test.ts
rename to app/dashboard/src/utilities/__tests__/shortcuts.test.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/__tests__/validation.test.ts b/app/dashboard/src/utilities/__tests__/validation.test.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/__tests__/validation.test.ts
rename to app/dashboard/src/utilities/__tests__/validation.test.ts
diff --git a/app/dashboard/src/utilities/accessToken.ts b/app/dashboard/src/utilities/accessToken.ts
new file mode 100644
index 00000000000..2a3c689994c
--- /dev/null
+++ b/app/dashboard/src/utilities/accessToken.ts
@@ -0,0 +1,20 @@
+/** @file Types for IPC events sent between Electron's main process and its renderer process. */
+
+// ===================
+// === AccessToken ===
+// ===================
+
+/** Payload for the `save-access-token` event that saves an access token to a credentials file. */
+export interface AccessToken {
+ /** The JWT token to save. */
+ readonly accessToken: string
+ /** The Cognito app integration client id. */
+ readonly clientId: string
+ /** The refresh token taken from authorization flow. */
+ readonly refreshToken: string
+ /** The Cognito url to refresh the token. */
+ readonly refreshUrl: string
+ /** The when the token will expire.
+ * This is a string representation of a date in ISO 8601 format (e.g. "2021-01-01T00:00:00Z"). */
+ readonly expireAt: string
+}
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/appBaseUrl.ts b/app/dashboard/src/utilities/appBaseUrl.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/appBaseUrl.ts
rename to app/dashboard/src/utilities/appBaseUrl.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/array.ts b/app/dashboard/src/utilities/array.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/array.ts
rename to app/dashboard/src/utilities/array.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/dateTime.ts b/app/dashboard/src/utilities/dateTime.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/dateTime.ts
rename to app/dashboard/src/utilities/dateTime.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/download.ts b/app/dashboard/src/utilities/download.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/download.ts
rename to app/dashboard/src/utilities/download.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/drag.ts b/app/dashboard/src/utilities/drag.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/drag.ts
rename to app/dashboard/src/utilities/drag.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/error.ts b/app/dashboard/src/utilities/error.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/error.ts
rename to app/dashboard/src/utilities/error.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/event.ts b/app/dashboard/src/utilities/event.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/event.ts
rename to app/dashboard/src/utilities/event.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/fileIcon.ts b/app/dashboard/src/utilities/fileIcon.ts
similarity index 79%
rename from app/ide-desktop/lib/dashboard/src/utilities/fileIcon.ts
rename to app/dashboard/src/utilities/fileIcon.ts
index 2ec3d3b1805..afb301d5973 100644
--- a/app/ide-desktop/lib/dashboard/src/utilities/fileIcon.ts
+++ b/app/dashboard/src/utilities/fileIcon.ts
@@ -1,5 +1,5 @@
/** @file Return the appropriate file icon given the file name. */
-import TextIcon from 'enso-assets/text.svg'
+import TextIcon from '#/assets/text.svg'
/** Return the appropriate icon given the file name. */
export function fileIcon() {
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/fileInfo.ts b/app/dashboard/src/utilities/fileInfo.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/fileInfo.ts
rename to app/dashboard/src/utilities/fileInfo.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/geometry.ts b/app/dashboard/src/utilities/geometry.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/geometry.ts
rename to app/dashboard/src/utilities/geometry.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/github.ts b/app/dashboard/src/utilities/github.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/github.ts
rename to app/dashboard/src/utilities/github.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/indent.ts b/app/dashboard/src/utilities/indent.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/indent.ts
rename to app/dashboard/src/utilities/indent.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/inputBindings.ts b/app/dashboard/src/utilities/inputBindings.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/inputBindings.ts
rename to app/dashboard/src/utilities/inputBindings.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/jsonSchema.ts b/app/dashboard/src/utilities/jsonSchema.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/jsonSchema.ts
rename to app/dashboard/src/utilities/jsonSchema.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/mergeRefs.ts b/app/dashboard/src/utilities/mergeRefs.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/mergeRefs.ts
rename to app/dashboard/src/utilities/mergeRefs.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/newtype.ts b/app/dashboard/src/utilities/newtype.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/newtype.ts
rename to app/dashboard/src/utilities/newtype.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/object.ts b/app/dashboard/src/utilities/object.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/object.ts
rename to app/dashboard/src/utilities/object.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/parseUserEmails.ts b/app/dashboard/src/utilities/parseUserEmails.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/parseUserEmails.ts
rename to app/dashboard/src/utilities/parseUserEmails.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/pasteData.ts b/app/dashboard/src/utilities/pasteData.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/pasteData.ts
rename to app/dashboard/src/utilities/pasteData.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/permissions.ts b/app/dashboard/src/utilities/permissions.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/permissions.ts
rename to app/dashboard/src/utilities/permissions.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/safeJsonParse.ts b/app/dashboard/src/utilities/safeJsonParse.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/safeJsonParse.ts
rename to app/dashboard/src/utilities/safeJsonParse.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/sanitizedEventTargets.ts b/app/dashboard/src/utilities/sanitizedEventTargets.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/sanitizedEventTargets.ts
rename to app/dashboard/src/utilities/sanitizedEventTargets.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/set.ts b/app/dashboard/src/utilities/set.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/set.ts
rename to app/dashboard/src/utilities/set.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/sorting.ts b/app/dashboard/src/utilities/sorting.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/sorting.ts
rename to app/dashboard/src/utilities/sorting.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/string.ts b/app/dashboard/src/utilities/string.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/string.ts
rename to app/dashboard/src/utilities/string.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/style.ts b/app/dashboard/src/utilities/style.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/style.ts
rename to app/dashboard/src/utilities/style.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/tailwindMerge.ts b/app/dashboard/src/utilities/tailwindMerge.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/tailwindMerge.ts
rename to app/dashboard/src/utilities/tailwindMerge.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/tailwindVariants.ts b/app/dashboard/src/utilities/tailwindVariants.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/tailwindVariants.ts
rename to app/dashboard/src/utilities/tailwindVariants.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/uniqueString.ts b/app/dashboard/src/utilities/uniqueString.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/uniqueString.ts
rename to app/dashboard/src/utilities/uniqueString.ts
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/validation.ts b/app/dashboard/src/utilities/validation.ts
similarity index 100%
rename from app/ide-desktop/lib/dashboard/src/utilities/validation.ts
rename to app/dashboard/src/utilities/validation.ts
diff --git a/app/ide-desktop/lib/dashboard/tailwind.config.js b/app/dashboard/tailwind.config.js
similarity index 100%
rename from app/ide-desktop/lib/dashboard/tailwind.config.js
rename to app/dashboard/tailwind.config.js
diff --git a/app/ide-desktop/lib/dashboard/tsconfig.json b/app/dashboard/tsconfig.json
similarity index 56%
rename from app/ide-desktop/lib/dashboard/tsconfig.json
rename to app/dashboard/tsconfig.json
index 1af3a4fb115..a50e793d18f 100644
--- a/app/ide-desktop/lib/dashboard/tsconfig.json
+++ b/app/dashboard/tsconfig.json
@@ -1,5 +1,5 @@
{
- "extends": "../../tsconfig.json",
+ "extends": "../tsconfig.json",
"include": [
"src",
"e2e",
@@ -14,15 +14,9 @@
"compilerOptions": {
"composite": true,
"noEmit": false,
- "outDir": "../../../../node_modules/.cache/tsc",
+ "outDir": "../../node_modules/.cache/tsc",
"paths": { "#/*": ["./src/*"] },
"target": "ESNext",
- "lib": ["ESNext", "DOM", "DOM.Iterable", "ES2023"],
-
- "plugins": [
- {
- "name": "ts-plugin-namespace-auto-import"
- }
- ]
+ "lib": ["ESNext", "DOM", "DOM.Iterable", "ES2023"]
}
}
diff --git a/app/ide-desktop/lib/dashboard/vite.config.ts b/app/dashboard/vite.config.ts
similarity index 98%
rename from app/ide-desktop/lib/dashboard/vite.config.ts
rename to app/dashboard/vite.config.ts
index 2684fd282ac..8aca4c86de6 100644
--- a/app/ide-desktop/lib/dashboard/vite.config.ts
+++ b/app/dashboard/vite.config.ts
@@ -42,7 +42,6 @@ export default vite.defineConfig({
},
},
define: {
- IS_VITE: JSON.stringify(true),
// The sole hardcoded usage of `global` in aws-amplify.
'global.TYPED_ARRAY_SUPPORT': JSON.stringify(true),
...appConfig.getDefines(),
diff --git a/app/ide-desktop/lib/dashboard/vite.test.config.ts b/app/dashboard/vite.test.config.ts
similarity index 91%
rename from app/ide-desktop/lib/dashboard/vite.test.config.ts
rename to app/dashboard/vite.test.config.ts
index a56351f49ce..db99d4bdc77 100644
--- a/app/ide-desktop/lib/dashboard/vite.test.config.ts
+++ b/app/dashboard/vite.test.config.ts
@@ -7,8 +7,6 @@ import * as appConfig from 'enso-common/src/appConfig'
// === Configuration ===
// =====================
-/* eslint-disable @typescript-eslint/naming-convention */
-
appConfig.loadTestEnvironmentVariables()
const CONFIG = (await import('./vite.config')).default
@@ -35,6 +33,7 @@ export default vite.mergeConfig(
],
},
define: {
+ // eslint-disable-next-line @typescript-eslint/naming-convention
'process.env.IS_IN_PLAYWRIGHT_TEST': JSON.stringify(`${true}`),
},
})
diff --git a/app/ide-desktop/lib/dashboard/vitest.config.ts b/app/dashboard/vitest.config.ts
similarity index 92%
rename from app/ide-desktop/lib/dashboard/vitest.config.ts
rename to app/dashboard/vitest.config.ts
index 5b4255978a9..bc1d2b3e7e3 100644
--- a/app/ide-desktop/lib/dashboard/vitest.config.ts
+++ b/app/dashboard/vitest.config.ts
@@ -5,8 +5,6 @@ import * as vitestConfig from 'vitest/config'
import * as appConfig from 'enso-common/src/appConfig'
-/* eslint-disable @typescript-eslint/naming-convention */
-
appConfig.loadTestEnvironmentVariables()
// @ts-expect-error This is required, otherwise importing node modules is broken.
// This is required for `datalinkSchema.test.ts`.
diff --git a/app/ide-desktop/eslint.config.js b/app/eslint.config.mjs
similarity index 95%
rename from app/ide-desktop/eslint.config.js
rename to app/eslint.config.mjs
index 0dec27700e6..ec9da1a1029 100644
--- a/app/ide-desktop/eslint.config.js
+++ b/app/eslint.config.mjs
@@ -31,10 +31,10 @@ const NAME = 'enso'
* `yargs` is a modules we explicitly want the default imports of.
* `node:process` is here because `process.on` does not exist on the namespace import. */
const DEFAULT_IMPORT_ONLY_MODULES =
- '@vitejs\\u002Fplugin-react|node:process|chalk|string-length|yargs|yargs\\u002Fyargs|sharp|to-ico|connect|morgan|serve-static|tiny-invariant|clsx|create-servers|electron-is-dev|fast-glob|esbuild-plugin-.+|opener|tailwindcss.*|enso-assets.*|@modyfi\\u002Fvite-plugin-yaml|is-network-error|validator.+|.*[.]json$'
+ '@vitejs\\u002Fplugin-react|node:process|chalk|string-length|yargs|yargs\\u002Fyargs|sharp|to-ico|connect|morgan|serve-static|tiny-invariant|clsx|create-servers|electron-is-dev|fast-glob|esbuild-plugin-.+|opener|tailwindcss.*|@modyfi\\u002Fvite-plugin-yaml|build-info|is-network-error|validator.+|.*[.]json$'
const OUR_MODULES = 'enso-.*'
const RELATIVE_MODULES =
- 'bin\\u002Fproject-manager|bin\\u002Fserver|config\\u002Fparser|authentication|config|debug|desktop-environment|detect|file-associations|index|ipc|log|naming|paths|preload|project-management|security|url-associations|#\\u002F.*'
+ 'bin\\u002Fproject-manager|bin\\u002Fserver|config\\u002Fparser|authentication|config|debug|detect|file-associations|index|ipc|log|naming|paths|preload|project-management|security|url-associations|content-config|desktop-environment|#\\u002F.*'
const ALLOWED_DEFAULT_IMPORT_MODULES = `${DEFAULT_IMPORT_ONLY_MODULES}|postcss|ajv\\u002Fdist\\u002F2020|${RELATIVE_MODULES}`
const STRING_LITERAL = ':matches(Literal[raw=/^["\']/], TemplateLiteral)'
const NOT_CAMEL_CASE = '/^(?!_?[a-z][a-z0-9*]*([A-Z0-9][a-z0-9]*)*$)(?!React$)/'
@@ -50,10 +50,6 @@ const NOT_CONSTANT_CASE = `/^(?!${WHITELISTED_CONSTANTS}$|_?[A-Z][A-Z0-9]*(_[A-Z
// - once explicitly disallowing `declare`s in regular `.ts`.
/** @type {{ selector: string; message: string; }[]} */
const RESTRICTED_SYNTAXES = [
- {
- selector: ':matches(ImportDeclaration:has(ImportSpecifier))',
- message: 'No {} imports and exports',
- },
{
selector: `ImportDeclaration[source.value=/^(?!(${ALLOWED_DEFAULT_IMPORT_MODULES})$)[^.]/] > ImportDefaultSpecifier`,
message:
@@ -460,18 +456,18 @@ export default [
},
{
files: [
- 'lib/dashboard/src/**/*.ts',
- 'lib/dashboard/src/**/*.mts',
- 'lib/dashboard/src/**/*.cts',
- 'lib/dashboard/src/**/*.tsx',
- 'lib/dashboard/src/**/*.mtsx',
- 'lib/dashboard/src/**/*.ctsx',
- 'lib/dashboard/mock/**/*.ts',
- 'lib/dashboard/mock/**/*.mts',
- 'lib/dashboard/mock/**/*.cts',
- 'lib/dashboard/mock/**/*.tsx',
- 'lib/dashboard/mock/**/*.mtsx',
- 'lib/dashboard/mock/**/*.ctsx',
+ 'dashboard/src/**/*.ts',
+ 'dashboard/src/**/*.mts',
+ 'dashboard/src/**/*.cts',
+ 'dashboard/src/**/*.tsx',
+ 'dashboard/src/**/*.mtsx',
+ 'dashboard/src/**/*.ctsx',
+ 'dashboard/mock/**/*.ts',
+ 'dashboard/mock/**/*.mts',
+ 'dashboard/mock/**/*.cts',
+ 'dashboard/mock/**/*.tsx',
+ 'dashboard/mock/**/*.mtsx',
+ 'dashboard/mock/**/*.ctsx',
],
rules: {
'no-restricted-properties': [
@@ -486,12 +482,12 @@ export default [
},
{
files: [
- 'lib/dashboard/e2e/**/*.ts',
- 'lib/dashboard/e2e/**/*.mts',
- 'lib/dashboard/e2e/**/*.cts',
- 'lib/dashboard/e2e/**/*.tsx',
- 'lib/dashboard/e2e/**/*.mtsx',
- 'lib/dashboard/e2e/**/*.ctsx',
+ 'dashboard/e2e/**/*.ts',
+ 'dashboard/e2e/**/*.mts',
+ 'dashboard/e2e/**/*.cts',
+ 'dashboard/e2e/**/*.tsx',
+ 'dashboard/e2e/**/*.mtsx',
+ 'dashboard/e2e/**/*.ctsx',
],
rules: {
'no-restricted-properties': [
diff --git a/app/gui2/env.d.ts b/app/gui2/env.d.ts
index 87dcf9ce438..0ffbb98be19 100644
--- a/app/gui2/env.d.ts
+++ b/app/gui2/env.d.ts
@@ -19,7 +19,7 @@ interface Window {
* # Safety
*
* We're assuming that the main process has exposed the `fileBrowserApi` context bridge (see
- * `app/ide-desktop/lib/client/src/preload.ts` for details), and that it contains the functions defined in this
+ * `app/client/src/preload.ts` for details), and that it contains the functions defined in this
* interface.
*/
interface FileBrowserApi {
diff --git a/app/gui2/package.json b/app/gui2/package.json
index 613c7d7ab60..0622b8f3ca3 100644
--- a/app/gui2/package.json
+++ b/app/gui2/package.json
@@ -54,10 +54,10 @@
"@lexical/code": "^0.16.0",
"@lexical/link": "^0.16.0",
"@lexical/list": "^0.16.0",
- "@lexical/selection": "^0.16.0",
"@lexical/markdown": "^0.16.0",
"@lexical/plain-text": "^0.16.0",
"@lexical/rich-text": "^0.16.0",
+ "@lexical/selection": "^0.16.0",
"@lexical/table": "^0.16.0",
"@lexical/utils": "^0.16.0",
"@lezer/common": "^1.1.0",
@@ -113,6 +113,7 @@
"@types/mapbox-gl": "^2.7.13",
"@types/node": "^20.11.21",
"@types/shuffle-seed": "^1.1.0",
+ "@types/tar": "^6.1.4",
"@types/unbzip2-stream": "^1.4.3",
"@types/wicg-file-system-access": "^2023.10.2",
"@types/ws": "^8.5.5",
@@ -127,10 +128,7 @@
"cross-env": "^7.0.3",
"css.escape": "^1.5.1",
"d3": "^7.4.0",
- "react": "^18.3.1",
- "react-dom": "^18.3.1",
"enso-common": "workspace:*",
- "enso-project-manager-shim": "workspace:*",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.22.0",
"floating-vue": "^2.0.0-beta.24",
@@ -141,10 +139,12 @@
"postcss-nesting": "^12.0.1",
"prettier": "^3.3.2",
"prettier-plugin-organize-imports": "^4.0.0",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
"shuffle-seed": "^1.1.6",
"sql-formatter": "^13.0.0",
"tailwindcss": "^3.2.7",
- "tar": "^6.2.0",
+ "tar": "^6.2.1",
"tsx": "^4.7.1",
"typescript": "^5.5.3",
"unbzip2-stream": "^1.4.3",
@@ -152,6 +152,7 @@
"vite-plugin-vue-devtools": "7.3.5",
"vitest": "^1.3.1",
"vue-react-wrapper": "^0.3.1",
- "vue-tsc": "^2.0.24"
+ "vue-tsc": "^2.0.24",
+ "yaml": "^2.4.5"
}
}
diff --git a/app/gui2/project-manager-shim-middleware/desktopEnvironment.ts b/app/gui2/project-manager-shim-middleware/desktopEnvironment.ts
new file mode 100644
index 00000000000..dd29a004609
--- /dev/null
+++ b/app/gui2/project-manager-shim-middleware/desktopEnvironment.ts
@@ -0,0 +1,78 @@
+/** @file This module contains the logic for the detection of user-specific desktop environment attributes. */
+import * as childProcess from 'node:child_process'
+import * as os from 'node:os'
+import * as path from 'node:path'
+
+export const DOCUMENTS = getDocumentsPath()
+
+const CHILD_PROCESS_TIMEOUT = 3000
+
+/**
+ * Detects path of the user documents directory depending on the operating system.
+ */
+function getDocumentsPath(): string | undefined {
+ if (process.platform === 'linux') {
+ return getLinuxDocumentsPath()
+ } else if (process.platform === 'darwin') {
+ return getMacOsDocumentsPath()
+ } else if (process.platform === 'win32') {
+ return getWindowsDocumentsPath()
+ } else {
+ return
+ }
+}
+
+/**
+ * Returns the user documents path on Linux.
+ */
+function getLinuxDocumentsPath(): string {
+ const xdgDocumentsPath = getXdgDocumentsPath()
+
+ return xdgDocumentsPath ?? path.join(os.homedir(), 'enso')
+}
+
+/**
+ * Gets the documents directory from the XDG directory management system.
+ */
+function getXdgDocumentsPath(): string | undefined {
+ const out = childProcess.spawnSync('xdg-user-dir', ['DOCUMENTS'], {
+ timeout: CHILD_PROCESS_TIMEOUT,
+ })
+
+ if (out.error !== undefined) {
+ return
+ } else {
+ return out.stdout.toString().trim()
+ }
+}
+
+/**
+ * Get the user documents path. On macOS, `Documents` acts as a symlink pointing to the
+ * real locale-specific user documents directory.
+ */
+function getMacOsDocumentsPath(): string {
+ return path.join(os.homedir(), 'Documents')
+}
+
+/**
+ * Get the path to the `My Documents` Windows directory.
+ */
+function getWindowsDocumentsPath(): string | undefined {
+ const out = childProcess.spawnSync(
+ 'reg',
+ [
+ 'query',
+ 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders',
+ '/v',
+ 'personal',
+ ],
+ { timeout: CHILD_PROCESS_TIMEOUT },
+ )
+
+ if (out.error !== undefined) {
+ return
+ } else {
+ const stdoutString = out.stdout.toString()
+ return stdoutString.split(/\s\s+/)[4]
+ }
+}
diff --git a/app/gui2/project-manager-shim-middleware/index.ts b/app/gui2/project-manager-shim-middleware/index.ts
new file mode 100644
index 00000000000..0ea6949c83d
--- /dev/null
+++ b/app/gui2/project-manager-shim-middleware/index.ts
@@ -0,0 +1,449 @@
+/** @file A HTTP server middleware which handles routes normally proxied through to
+ * the Project Manager. */
+import * as fsSync from 'node:fs'
+import * as fs from 'node:fs/promises'
+import * as http from 'node:http'
+import * as path from 'node:path'
+
+import * as tar from 'tar'
+import * as yaml from 'yaml'
+
+import * as common from 'enso-common'
+import GLOBAL_CONFIG from 'enso-common/src/config.json' assert { type: 'json' }
+
+import * as projectManagement from './projectManagement'
+
+// =================
+// === Constants ===
+// =================
+
+const HTTP_STATUS_OK = 200
+const HTTP_STATUS_BAD_REQUEST = 400
+const HTTP_STATUS_NOT_FOUND = 404
+const PROJECTS_ROOT_DIRECTORY = projectManagement.getProjectsDirectory()
+
+// =============
+// === Types ===
+// =============
+
+/** Details of a project. */
+interface ProjectMetadata {
+ /** The name of the project. */
+ readonly name: string
+ /** The namespace of the project. */
+ readonly namespace: string
+ /** The project id. */
+ readonly id: string
+ /** The Enso Engine version to use for the project, represented by a semver version
+ * string.
+ *
+ * If the edition associated with the project could not be resolved, the
+ * engine version may be missing. */
+ readonly engineVersion?: string
+ /** The project creation time. */
+ readonly created: string
+ /** The last opened datetime. */
+ readonly lastOpened?: string
+}
+
+/** Attributes of a file or folder. */
+interface Attributes {
+ readonly creationTime: string
+ readonly lastAccessTime: string
+ readonly lastModifiedTime: string
+ readonly byteSize: number
+}
+
+/** Metadata for an arbitrary file system entry. */
+type FileSystemEntry = DirectoryEntry | FileEntry | ProjectEntry
+
+/** The discriminator value for {@link FileSystemEntry}. */
+export enum FileSystemEntryType {
+ DirectoryEntry = 'DirectoryEntry',
+ ProjectEntry = 'ProjectEntry',
+ FileEntry = 'FileEntry',
+}
+
+/** Metadata for a file. */
+interface FileEntry {
+ readonly type: FileSystemEntryType.FileEntry
+ readonly path: string
+ readonly attributes: Attributes
+}
+
+/** Metadata for a directory. */
+interface DirectoryEntry {
+ readonly type: FileSystemEntryType.DirectoryEntry
+ readonly path: string
+ readonly attributes: Attributes
+}
+
+/** Metadata for a project. */
+interface ProjectEntry {
+ readonly type: FileSystemEntryType.ProjectEntry
+ readonly path: string
+ readonly metadata: ProjectMetadata
+ readonly attributes: Attributes
+}
+
+// ====================================
+// === projectManagerShimMiddleware ===
+// ====================================
+
+/** A middleware that handles */
+export default function projectManagerShimMiddleware(
+ request: http.IncomingMessage,
+ response: http.ServerResponse,
+ next: () => void,
+) {
+ const requestUrl = request.url
+ const requestPath = requestUrl?.split('?')[0]?.split('#')[0]
+ if (requestUrl != null && requestUrl.startsWith('/api/project-manager/')) {
+ const actualUrl = new URL(
+ requestUrl.replace(/^\/api\/project-manager/, GLOBAL_CONFIG.projectManagerHttpEndpoint),
+ )
+ request.pipe(
+ http.request(
+ // `...actualUrl` does NOT work because `URL` properties are not enumerable.
+ {
+ headers: request.headers,
+ host: actualUrl.host,
+ hostname: actualUrl.hostname,
+ method: request.method,
+ path: actualUrl.pathname,
+ port: actualUrl.port,
+ protocol: actualUrl.protocol,
+ },
+ (actualResponse) => {
+ response.writeHead(
+ // This is SAFE. The documentation says:
+ // Only valid for response obtained from ClientRequest.
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ actualResponse.statusCode!,
+ actualResponse.statusMessage,
+ actualResponse.headers,
+ )
+ actualResponse.pipe(response, { end: true })
+ },
+ ),
+ { end: true },
+ )
+ } else if (request.method === 'POST') {
+ switch (requestPath) {
+ case '/api/upload-file': {
+ const url = new URL(`https://example.com/${requestUrl}`)
+ const fileName = url.searchParams.get('file_name')
+ const directory = url.searchParams.get('directory') ?? PROJECTS_ROOT_DIRECTORY
+ if (fileName == null) {
+ response
+ .writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS)
+ .end('Request is missing search parameter `file_name`.')
+ } else {
+ const filePath = path.join(directory, fileName)
+ void fs
+ .writeFile(filePath, request)
+ .then(() => {
+ response
+ .writeHead(HTTP_STATUS_OK, [
+ ['Content-Length', String(filePath.length)],
+ ['Content-Type', 'text/plain'],
+ ...common.COOP_COEP_CORP_HEADERS,
+ ])
+ .end(filePath)
+ })
+ .catch((e) => {
+ console.error(e)
+ response.writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS).end()
+ })
+ }
+ break
+ }
+ // This endpoint should only be used when accessing the app from the browser.
+ // When accessing the app from Electron, the file input event will have the
+ // full system path.
+ case '/api/upload-project': {
+ const url = new URL(`https://example.com/${requestUrl}`)
+ const directory = url.searchParams.get('directory')
+ const name = url.searchParams.get('name')
+ void projectManagement
+ .uploadBundle(request, directory, name)
+ .then((id) => {
+ response
+ .writeHead(HTTP_STATUS_OK, [
+ ['Content-Length', String(id.length)],
+ ['Content-Type', 'text/plain'],
+ ...common.COOP_COEP_CORP_HEADERS,
+ ])
+ .end(id)
+ })
+ .catch(() => {
+ response.writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS).end()
+ })
+ break
+ }
+ case '/api/run-project-manager-command': {
+ const cliArguments: unknown = JSON.parse(
+ new URL(`https://example.com/${requestUrl}`).searchParams.get('cli-arguments') ?? '[]',
+ )
+ if (
+ !Array.isArray(cliArguments) ||
+ !cliArguments.every((item): item is string => typeof item === 'string')
+ ) {
+ response
+ .writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS)
+ .end('Command arguments must be an array of strings.')
+ } else {
+ void (async () => {
+ const toJSONRPCResult = (result: unknown) =>
+ JSON.stringify({ jsonrpc: '2.0', id: 0, result })
+ const toJSONRPCError = (message: string, data?: unknown) =>
+ JSON.stringify({
+ jsonrpc: '2.0',
+ id: 0,
+ error: { code: 0, message, ...(data != null ? { data } : {}) },
+ })
+ let result = toJSONRPCError(`Error running Project Manager command.`, {
+ command: cliArguments,
+ })
+ try {
+ switch (cliArguments[0]) {
+ case '--filesystem-list': {
+ const directoryPath = cliArguments[1]
+ if (directoryPath != null) {
+ const entryNames = await fs.readdir(directoryPath)
+ const entries: FileSystemEntry[] = []
+ for (const entryName of entryNames) {
+ const entryPath = path.join(directoryPath, entryName)
+ if (isHidden(entryPath)) continue
+ const stat = await fs.stat(entryPath)
+ const attributes: Attributes = {
+ byteSize: stat.size,
+ creationTime: new Date(stat.ctimeMs).toISOString(),
+ lastAccessTime: new Date(stat.atimeMs).toISOString(),
+ lastModifiedTime: new Date(stat.mtimeMs).toISOString(),
+ }
+ if (stat.isFile()) {
+ entries.push({
+ type: FileSystemEntryType.FileEntry,
+ path: entryPath,
+ attributes,
+ } satisfies FileEntry)
+ } else {
+ try {
+ const packageMetadataPath = path.join(entryPath, 'package.yaml')
+ const projectMetadataPath = path.join(
+ entryPath,
+ projectManagement.PROJECT_METADATA_RELATIVE_PATH,
+ )
+ const packageMetadataContents = await fs.readFile(packageMetadataPath)
+ const projectMetadataContents = await fs.readFile(projectMetadataPath)
+ const metadata = extractProjectMetadata(
+ yaml.parse(packageMetadataContents.toString()),
+ JSON.parse(projectMetadataContents.toString()),
+ )
+ if (metadata != null) {
+ // This is a project.
+ entries.push({
+ type: FileSystemEntryType.ProjectEntry,
+ path: entryPath,
+ attributes,
+ metadata,
+ } satisfies ProjectEntry)
+ } else {
+ // This error moves control flow to the
+ // `catch` clause directly below.
+ // eslint-disable-next-line no-restricted-syntax
+ throw new Error('Invalid project metadata.')
+ }
+ } catch {
+ // This is a regular directory, not a project.
+ entries.push({
+ type: FileSystemEntryType.DirectoryEntry,
+ path: entryPath,
+ attributes,
+ } satisfies DirectoryEntry)
+ }
+ }
+ }
+ result = toJSONRPCResult({ entries })
+ }
+ break
+ }
+ case '--filesystem-create-directory': {
+ const directoryPath = cliArguments[1]
+ if (directoryPath != null) {
+ await fs.mkdir(directoryPath, { recursive: true })
+ result = toJSONRPCResult(null)
+ }
+ break
+ }
+ case '--filesystem-write-path': {
+ const filePath = cliArguments[1]
+ if (filePath != null) {
+ await new Promise((resolve, reject) => {
+ request
+ .pipe(fsSync.createWriteStream(filePath), {
+ end: true,
+ })
+ .on('close', resolve)
+ .on('error', reject)
+ })
+ result = toJSONRPCResult(null)
+ }
+ break
+ }
+ case '--filesystem-move-from': {
+ const sourcePath = cliArguments[1]
+ const destinationPath = cliArguments[3]
+ if (
+ sourcePath != null &&
+ cliArguments[2] === '--filesystem-move-to' &&
+ destinationPath != null
+ ) {
+ await fs.rename(sourcePath, destinationPath)
+ result = toJSONRPCResult(null)
+ }
+ break
+ }
+ case '--filesystem-delete': {
+ const fileOrDirectoryPath = cliArguments[1]
+ if (fileOrDirectoryPath != null) {
+ await fs.rm(fileOrDirectoryPath, { recursive: true })
+ result = toJSONRPCResult(null)
+ }
+ break
+ }
+ default: {
+ // Ignored. `result` retains its original value indicating an error.
+ }
+ }
+ } catch {
+ // Ignored. `result` retains its original value indicating an error.
+ }
+ const buffer = Buffer.from(result)
+ response
+ .writeHead(HTTP_STATUS_OK, [
+ ['Content-Length', String(buffer.byteLength)],
+ ['Content-Type', 'application/json'],
+ ...common.COOP_COEP_CORP_HEADERS,
+ ])
+ .end(buffer)
+ })()
+ }
+ break
+ }
+ default: {
+ const downloadProjectMatch = requestPath?.match(
+ /^[/]api[/]project-manager[/]projects[/]([^/]+)[/]enso-project$/,
+ )
+ if (downloadProjectMatch) {
+ const uuid = downloadProjectMatch[1]
+ void fs.readdir(PROJECTS_ROOT_DIRECTORY).then(async (filenames) => {
+ let success = false
+ for (const filename of filenames) {
+ try {
+ const projectRoot = path.join(PROJECTS_ROOT_DIRECTORY, filename)
+ const stat = await fs.stat(projectRoot)
+ if (stat.isDirectory()) {
+ const metadataPath = path.join(
+ projectRoot,
+ projectManagement.PROJECT_METADATA_RELATIVE_PATH,
+ )
+ const metadataContents = await fs.readFile(metadataPath)
+ const metadata: unknown = JSON.parse(metadataContents.toString())
+ if (
+ typeof metadata === 'object' &&
+ metadata != null &&
+ 'id' in metadata &&
+ metadata.id === uuid
+ ) {
+ response.writeHead(HTTP_STATUS_OK, [
+ ['Content-Type', 'application/gzip+x-enso-project'],
+ ...common.COOP_COEP_CORP_HEADERS,
+ ])
+ tar
+ .create({ gzip: true, cwd: projectRoot }, [projectRoot])
+ .pipe(response, { end: true })
+ success = true
+ break
+ }
+ }
+ } catch {
+ // Ignored.
+ }
+ }
+ if (!success) {
+ response.writeHead(HTTP_STATUS_NOT_FOUND, common.COOP_COEP_CORP_HEADERS).end()
+ }
+ })
+ break
+ }
+ response.writeHead(HTTP_STATUS_NOT_FOUND, common.COOP_COEP_CORP_HEADERS).end()
+ break
+ }
+ }
+ } else if (request.method === 'GET' && requestPath === '/api/root-directory') {
+ response
+ .writeHead(HTTP_STATUS_OK, [
+ ['Content-Length', String(PROJECTS_ROOT_DIRECTORY.length)],
+ ['Content-Type', 'text/plain'],
+ ...common.COOP_COEP_CORP_HEADERS,
+ ])
+ .end(PROJECTS_ROOT_DIRECTORY)
+ } else {
+ next()
+ }
+}
+
+/** Return a {@link ProjectMetadata} if the metadata is a valid metadata object,
+ * else return `null`. */
+function extractProjectMetadata(yamlObj: unknown, jsonObj: unknown): ProjectMetadata | null {
+ if (
+ typeof yamlObj !== 'object' ||
+ yamlObj == null ||
+ typeof jsonObj !== 'object' ||
+ jsonObj == null
+ ) {
+ return null
+ } else {
+ const validDateString = (string: string) => {
+ const date = new Date(string)
+ return !Number.isNaN(Number(date)) ? date.toString() : null
+ }
+ const name = 'name' in yamlObj && typeof yamlObj.name === 'string' ? yamlObj.name : null
+ const namespace =
+ 'namespace' in yamlObj && typeof yamlObj.namespace === 'string' ? yamlObj.namespace : null
+ const engineVersion =
+ 'edition' in yamlObj && typeof yamlObj.edition === 'string' ? yamlObj.edition : null
+ const id = 'id' in jsonObj && typeof jsonObj.id === 'string' ? jsonObj.id : null
+ const created =
+ 'created' in jsonObj && typeof jsonObj.created === 'string' ?
+ validDateString(jsonObj.created)
+ : null
+ const lastOpened =
+ 'lastOpened' in jsonObj && typeof jsonObj.lastOpened === 'string' ?
+ validDateString(jsonObj.lastOpened)
+ : null
+ if (name != null && namespace != null && id != null && created != null) {
+ return {
+ name,
+ namespace,
+ id,
+ ...(engineVersion != null ? { engineVersion } : {}),
+ created,
+ ...(lastOpened != null ? { lastOpened } : {}),
+ } satisfies ProjectMetadata
+ } else {
+ return null
+ }
+ }
+}
+
+/**
+ * Checks if files that start with the dot.
+ * Note on Windows does not check the hidden property.
+ */
+function isHidden(filePath: string): boolean {
+ const dotfile = /(^|[\\/])\.[^\\/]+$/g
+ return dotfile.test(filePath)
+}
diff --git a/app/gui2/project-manager-shim-middleware/projectManagement.ts b/app/gui2/project-manager-shim-middleware/projectManagement.ts
new file mode 100644
index 00000000000..c6140692117
--- /dev/null
+++ b/app/gui2/project-manager-shim-middleware/projectManagement.ts
@@ -0,0 +1,440 @@
+/** @file This module contains functions for importing projects into the Project Manager.
+ *
+ * Eventually this module should be replaced with a new Project Manager API that supports
+ * importing projects.
+ * For now, we basically do the following:
+ * - if the project is already in the Project Manager's location, we just open it;
+ * - if the project is in a different location, we copy it to the Project Manager's location
+ * and open it.
+ * - if the project is a bundle, we extract it to the Project Manager's location and open it. */
+import * as crypto from 'node:crypto'
+import * as fs from 'node:fs'
+import * as os from 'node:os'
+import * as pathModule from 'node:path'
+import type * as stream from 'node:stream'
+
+import * as tar from 'tar'
+
+import * as common from 'enso-common'
+import * as buildUtils from 'enso-common/src/buildUtils'
+import * as desktopEnvironment from './desktopEnvironment'
+
+const logger = console
+
+// =================
+// === Constants ===
+// =================
+
+export const PACKAGE_METADATA_RELATIVE_PATH = 'package.yaml'
+export const PROJECT_METADATA_RELATIVE_PATH = '.enso/project.json'
+/** The filename suffix for the project bundle, including the leading period character. */
+const BUNDLED_PROJECT_SUFFIX = '.enso-project'
+
+// ======================
+// === Project Import ===
+// ======================
+
+/** Open a project from the given path. Path can be either a source file under the project root,
+ * or the project bundle. If needed, the project will be imported into the Project Manager-enabled
+ * location.
+ * @returns Project ID (from Project Manager's metadata) identifying the imported project.
+ * @throws {Error} if the path does not belong to a valid project. */
+export function importProjectFromPath(
+ openedPath: string,
+ directory?: string | null,
+ name: string | null = null,
+): string {
+ directory ??= getProjectsDirectory()
+ if (pathModule.extname(openedPath).endsWith(BUNDLED_PROJECT_SUFFIX)) {
+ logger.log(`Path '${openedPath}' denotes a bundled project.`)
+ // The second part of condition is for the case when someone names a directory
+ // like `my-project.enso-project` and stores the project there.
+ // Not the most fortunate move, but...
+ if (isProjectRoot(openedPath)) {
+ return importDirectory(openedPath, directory, name)
+ } else {
+ // Project bundle was provided, so we need to extract it first.
+ return importBundle(openedPath, directory, name)
+ }
+ } else {
+ logger.log(`Opening non-bundled file: '${openedPath}'.`)
+ const rootPath = getProjectRoot(openedPath)
+ // Check if the project root is under the projects directory. If it is, we can open it.
+ // Otherwise, we need to install it first.
+ if (rootPath == null) {
+ const productName = common.PRODUCT_NAME
+ const message = `File '${openedPath}' does not belong to the ${productName} project.`
+ throw new Error(message)
+ } else {
+ return importDirectory(rootPath, directory, name)
+ }
+ }
+}
+
+/** Import the project from a bundle.
+ * @returns Project ID (from Project Manager's metadata) identifying the imported project. */
+export function importBundle(
+ bundlePath: string,
+ directory?: string | null,
+ name: string | null = null,
+): string {
+ directory ??= getProjectsDirectory()
+ logger.log(`Importing project '${bundlePath}' from bundle${name != null ? ` as '${name}'` : ''}.`)
+ // The bundle is a tarball, so we just need to extract it to the right location.
+ const bundlePrefix = prefixInBundle(bundlePath)
+ // We care about spurious '.' and '..' when stripping paths but not when generating name.
+ const normalizedBundlePrefix =
+ bundlePrefix != null ?
+ pathModule.normalize(bundlePrefix).replace(/[\\/]+$/, '') // Also strip trailing slash.
+ : null
+ const dirNameBase =
+ (
+ normalizedBundlePrefix != null &&
+ normalizedBundlePrefix !== '.' &&
+ normalizedBundlePrefix !== '..'
+ ) ?
+ normalizedBundlePrefix
+ : bundlePath
+ logger.log(`Bundle normalized prefix: '${String(normalizedBundlePrefix)}'.`)
+ const targetPath = generateDirectoryName(dirNameBase, directory)
+ logger.log(`Importing project as '${targetPath}'.`)
+ fs.mkdirSync(targetPath, { recursive: true })
+ // To be more resilient against different ways that user might attempt to create a bundle,
+ // we try to support both archives that:
+ // * contain a single directory with the project files - that directory name will be used
+ // to generate a new target directory name;
+ // * contain the project files directly - in this case, the archive filename will be used
+ // to generate a new target directory name.
+ // We try to tell apart these two cases by looking at the common prefix of the paths
+ // of the files in the archive. If there is any, everything is under a single directory,
+ // and we need to strip it.
+ //
+ // Additionally, we need to take into account that paths might be prefixed with `./` or not.
+ // Thus, we need to adjust the number of path components to strip accordingly.
+
+ logger.log(`Extracting bundle: '${bundlePath}' -> '${targetPath}'.`)
+
+ // Strip trailing separator and split the path into pieces.
+ const rootPieces = bundlePrefix != null ? bundlePrefix.split(/[\\/]/) : []
+
+ // If the last element is empty string (i.e. we had trailing separator), drop it.
+ if (rootPieces.length > 0 && rootPieces[rootPieces.length - 1] === '') {
+ rootPieces.pop()
+ }
+
+ tar.extract({
+ file: bundlePath,
+ cwd: targetPath,
+ sync: true,
+ strip: rootPieces.length,
+ })
+ return bumpMetadata(targetPath, directory, name ?? null)
+}
+
+/** Upload the project from a bundle. */
+export async function uploadBundle(
+ bundle: stream.Readable,
+ directory?: string | null,
+ name: string | null = null,
+): Promise {
+ directory ??= getProjectsDirectory()
+ logger.log(`Uploading project from bundle${name != null ? ` as '${name}'` : ''}.`)
+ const targetPath = generateDirectoryName(name ?? 'Project', directory)
+ fs.mkdirSync(targetPath, { recursive: true })
+ await new Promise((resolve) => {
+ bundle.pipe(tar.extract({ cwd: targetPath })).on('finish', resolve)
+ })
+ const entries = fs.readdirSync(targetPath)
+ const firstEntry = entries[0]
+ // If the directory only contains one subdirectory, replace the directory with its sole
+ // subdirectory.
+ if (entries.length === 1 && firstEntry != null) {
+ if (fs.statSync(pathModule.join(targetPath, firstEntry)).isDirectory()) {
+ const temporaryDirectoryName = targetPath + `_${crypto.randomUUID().split('-')[0] ?? ''}`
+ fs.renameSync(targetPath, temporaryDirectoryName)
+ fs.renameSync(pathModule.join(temporaryDirectoryName, firstEntry), targetPath)
+ fs.rmdirSync(temporaryDirectoryName)
+ }
+ }
+ return bumpMetadata(targetPath, directory, name ?? null)
+}
+
+/** Import the project so it becomes visible to the Project Manager.
+ * @returns The project ID (from the Project Manager's metadata) identifying the imported project.
+ * @throws {Error} if a race condition occurs when generating a unique project directory name. */
+export function importDirectory(
+ rootPath: string,
+ directory?: string | null,
+ name: string | null = null,
+): string {
+ directory ??= getProjectsDirectory()
+ if (isProjectInstalled(rootPath, directory)) {
+ // Project is already visible to Project Manager, so we can just return its ID.
+ logger.log(`Project already installed at '${rootPath}'.`)
+ const id = getProjectId(rootPath)
+ if (id != null) {
+ return id
+ } else {
+ throw new Error(`Project already installed, but missing metadata.`)
+ }
+ } else {
+ logger.log(`Importing a project copy from '${rootPath}'${name != null ? ` as '${name}'` : ''}.`)
+ const targetPath = generateDirectoryName(rootPath, directory)
+ if (fs.existsSync(targetPath)) {
+ throw new Error(`Project directory '${targetPath}' already exists.`)
+ } else {
+ logger.log(`Copying: '${rootPath}' -> '${targetPath}'.`)
+ fs.cpSync(rootPath, targetPath, { recursive: true })
+ // Update the project ID, so we are certain that it is unique.
+ // This would be violated, if we imported the same project multiple times.
+ return bumpMetadata(targetPath, directory, name ?? null)
+ }
+ }
+}
+
+// ================
+// === Metadata ===
+// ================
+
+/** The Project Manager's metadata associated with a project. */
+interface ProjectMetadata {
+ /** The ID of the project. It is only used in communication with project manager;
+ * it has no semantic meaning. */
+ readonly id: string
+ /** The project variant. This is currently always `UserProject`. */
+ readonly kind: 'UserProject'
+ /** The date at which the project was created, in RFC3339 format. */
+ readonly created: string
+ /** The date at which the project was last opened, in RFC3339 format. */
+ readonly lastOpened: string
+}
+
+/** A type guard function to check if an object conforms to the {@link ProjectMetadata} interface.
+ *
+ * This function checks if the input object has the required properties and correct types
+ * to match the {@link ProjectMetadata} interface. It can be used at runtime to validate that
+ * a given object has the expected shape.
+ * @param value - The object to check against the ProjectMetadata interface.
+ * @returns A boolean value indicating whether the object matches
+ * the {@link ProjectMetadata} interface. */
+function isProjectMetadata(value: unknown): value is ProjectMetadata {
+ return typeof value === 'object' && value != null && 'id' in value && typeof value.id === 'string'
+}
+
+/** Get the ID from the project metadata. */
+export function getProjectId(projectRoot: string): string | null {
+ return getMetadata(projectRoot)?.id ?? null
+}
+
+/** Get the package name. */
+function getPackageName(projectRoot: string) {
+ const path = pathModule.join(projectRoot, PACKAGE_METADATA_RELATIVE_PATH)
+ const contents = fs.readFileSync(path, { encoding: 'utf-8' })
+ const [, name] = contents.match(/^name: (.*)/) ?? []
+ return name ?? null
+}
+
+/** Update the package name. */
+export function updatePackageName(projectRoot: string, name: string) {
+ const path = pathModule.join(projectRoot, PACKAGE_METADATA_RELATIVE_PATH)
+ const contents = fs.readFileSync(path, { encoding: 'utf-8' })
+ const newContents = contents.replace(/^name: .*/, `name: ${name}`)
+ fs.writeFileSync(path, newContents)
+}
+
+/** Create a project's metadata. */
+export function createMetadata(): ProjectMetadata {
+ return {
+ id: generateId(),
+ kind: 'UserProject',
+ created: new Date().toISOString(),
+ lastOpened: new Date().toISOString(),
+ }
+}
+
+/** Retrieve the project's metadata. */
+export function getMetadata(projectRoot: string): ProjectMetadata | null {
+ const metadataPath = pathModule.join(projectRoot, PROJECT_METADATA_RELATIVE_PATH)
+ try {
+ const jsonText = fs.readFileSync(metadataPath, 'utf8')
+ const metadata: unknown = JSON.parse(jsonText)
+ return isProjectMetadata(metadata) ? metadata : null
+ } catch {
+ return null
+ }
+}
+
+/** Write the project's metadata. */
+export function writeMetadata(projectRoot: string, metadata: ProjectMetadata): void {
+ const metadataPath = pathModule.join(projectRoot, PROJECT_METADATA_RELATIVE_PATH)
+ fs.mkdirSync(pathModule.dirname(metadataPath), { recursive: true })
+ fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, buildUtils.INDENT_SIZE))
+}
+
+/** Update the project's metadata.
+ * If the provided updater does not return anything, the metadata file is left intact.
+ *
+ * Returns the metadata returned from the updater function. */
+export function updateMetadata(
+ projectRoot: string,
+ updater: (initialMetadata: ProjectMetadata) => ProjectMetadata,
+): ProjectMetadata {
+ const metadata = getMetadata(projectRoot)
+ const updatedMetadata = updater(metadata ?? createMetadata())
+ writeMetadata(projectRoot, updatedMetadata)
+ return updatedMetadata
+}
+
+// =========================
+// === Project Directory ===
+// =========================
+
+/** Check if the given path represents the root of an Enso project.
+ * This is decided by the presence of the Project Manager's metadata. */
+export function isProjectRoot(candidatePath: string): boolean {
+ const projectJsonPath = pathModule.join(candidatePath, PROJECT_METADATA_RELATIVE_PATH)
+ try {
+ fs.accessSync(projectJsonPath, fs.constants.R_OK)
+ return true
+ } catch {
+ return false
+ }
+}
+
+/** Check if this bundle is a compressed directory (rather than directly containing the project
+ * files). If it is, we return the path to the directory. Otherwise, we return `null`. */
+export function prefixInBundle(bundlePath: string): string | null {
+ // We need to look up the root directory among the tarball entries.
+ let commonPrefix: string | null = null
+ tar.list({
+ file: bundlePath,
+ sync: true,
+ onentry: (entry) => {
+ const path = entry.path
+ commonPrefix = commonPrefix == null ? path : buildUtils.getCommonPrefix(commonPrefix, path)
+ },
+ })
+
+ // ESLint doesn't know that `commonPrefix` can be not `null` here due to the `onentry` callback.
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+ return commonPrefix != null && commonPrefix !== '' ? commonPrefix : null
+}
+
+/** Generate a name for a project using given base string. A suffix is added if there is a
+ * collision.
+ *
+ * For example `Name` will become `Name_1` if there's already a directory named `Name`.
+ * If given a name like `Name_1` it will become `Name_2` if there is already a directory named
+ * `Name_1`. If a path containing multiple components is given, only the last component is used
+ * for the name. */
+export function generateDirectoryName(name: string, directory = getProjectsDirectory()): string {
+ // Use only the last path component.
+ name = pathModule.parse(name).name
+
+ // If the name already consists a suffix, reuse it.
+ const matches = name.match(/^(.*)_(\d+)$/)
+ const initialSuffix = -1
+ let suffix = initialSuffix
+ // Matches start with the whole match, so we need to skip it. Then come our two capture groups.
+ const [matchedName, matchedSuffix] = matches?.slice(1) ?? []
+ if (typeof matchedName !== 'undefined' && typeof matchedSuffix !== 'undefined') {
+ name = matchedName
+ suffix = parseInt(matchedSuffix)
+ }
+
+ let finalPath: string
+ // eslint-disable-next-line no-constant-condition
+ while (true) {
+ suffix++
+ const newName = `${name}${suffix === 0 ? '' : `_${suffix}`}`
+ const candidatePath = pathModule.join(directory, newName)
+ if (!fs.existsSync(candidatePath)) {
+ finalPath = candidatePath
+ break
+ }
+ }
+ return finalPath
+}
+
+/** Take a path to a file, presumably located in a project's subtree.Returns the path
+ * to the project's root directory or `null` if the file is not located in a project. */
+export function getProjectRoot(subtreePath: string): string | null {
+ let currentPath = subtreePath
+ while (!isProjectRoot(currentPath)) {
+ const parent = pathModule.dirname(currentPath)
+ if (parent === currentPath) {
+ // eslint-disable-next-line no-restricted-syntax
+ return null
+ }
+ currentPath = parent
+ }
+ return currentPath
+}
+
+/** Get the directory that stores Enso projects. */
+export function getProjectsDirectory(): string {
+ const documentsPath = desktopEnvironment.DOCUMENTS
+ if (documentsPath === undefined) {
+ return pathModule.join(os.homedir(), 'enso', 'projects')
+ } else {
+ return pathModule.join(documentsPath, 'enso-projects')
+ }
+}
+
+/** Check if the given project is installed, i.e. can be opened with the Project Manager. */
+export function isProjectInstalled(
+ projectRoot: string,
+ directory = getProjectsDirectory(),
+): boolean {
+ const projectRootParent = pathModule.dirname(projectRoot)
+ // Should resolve symlinks and relative paths. Normalize before comparison.
+ return pathModule.resolve(projectRootParent) === pathModule.resolve(directory)
+}
+
+// ==================
+// === Project ID ===
+// ==================
+
+/** Generate a unique UUID for a project. */
+export function generateId(): string {
+ return crypto.randomUUID()
+}
+
+/** Update the project's ID to a new, unique value, and its last opened date to the current date. */
+export function bumpMetadata(
+ projectRoot: string,
+ parentDirectory: string,
+ name: string | null,
+): string {
+ if (name == null) {
+ const currentName = getPackageName(projectRoot) ?? ''
+ let index: number | null = null
+ const prefix = `${currentName} `
+ for (const sibling of fs.readdirSync(parentDirectory, { withFileTypes: true })) {
+ if (sibling.isDirectory()) {
+ try {
+ const siblingPath = pathModule.join(parentDirectory, sibling.name)
+ const siblingName = getPackageName(siblingPath)
+ if (siblingName === currentName) {
+ index = index ?? 2
+ } else if (siblingName != null && siblingName.startsWith(prefix)) {
+ const suffix = siblingName.replace(prefix, '')
+ const [, numberString] = suffix.match(/^\((\d+)\)/) ?? []
+ if (numberString != null) {
+ index = Math.max(index ?? 2, Number(numberString) + 1)
+ }
+ }
+ } catch {
+ // Ignored - it is a directory but not a project.
+ }
+ }
+ }
+ name = index == null ? currentName : `${currentName} (${index})`
+ }
+ updatePackageName(projectRoot, name)
+ return updateMetadata(projectRoot, (metadata) => ({
+ ...metadata,
+ id: generateId(),
+ lastOpened: new Date().toISOString(),
+ })).id
+}
diff --git a/app/gui2/src/components/MarkdownEditor/BlockTypeMenu.vue b/app/gui2/src/components/MarkdownEditor/BlockTypeMenu.vue
index 944aa7a22a5..d4108d8648a 100644
--- a/app/gui2/src/components/MarkdownEditor/BlockTypeMenu.vue
+++ b/app/gui2/src/components/MarkdownEditor/BlockTypeMenu.vue
@@ -6,16 +6,15 @@ import type { Icon } from '@/util/iconName'
const blockType = defineModel({ required: true })
-const TODO: Icon = 'text'
const blockTypeIcon: Record = {
paragraph: 'text',
bullet: 'bullet-list',
- code: TODO,
- h1: TODO,
- h2: TODO,
- h3: TODO,
+ code: 'code',
+ h1: 'header1',
+ h2: 'header2',
+ h3: 'header3',
number: 'numbered-list',
- quote: TODO,
+ quote: 'quote',
}
const blockTypesOrdered: BlockType[] = [
'paragraph',
diff --git a/app/gui2/src/components/MarkdownEditor/FormatPropertiesBar.vue b/app/gui2/src/components/MarkdownEditor/FormatPropertiesBar.vue
index 3f0f9a323cf..101a3305a66 100644
--- a/app/gui2/src/components/MarkdownEditor/FormatPropertiesBar.vue
+++ b/app/gui2/src/components/MarkdownEditor/FormatPropertiesBar.vue
@@ -47,7 +47,7 @@ const close = () => (menuOpen.value = false)
/>
diff --git a/app/gui2/src/entrypoint.ts b/app/gui2/src/entrypoint.ts
index 0164cd2fae2..00ded7e2587 100644
--- a/app/gui2/src/entrypoint.ts
+++ b/app/gui2/src/entrypoint.ts
@@ -4,11 +4,11 @@ import * as vueQuery from '@tanstack/vue-query'
import { isOnLinux } from 'enso-common/src/detect'
import * as commonQuery from 'enso-common/src/queryClient'
import * as dashboard from 'enso-dashboard'
+import 'enso-dashboard/src/tailwind.css'
import { isDevMode } from 'shared/util/detect'
import { lazyVueInReact } from 'veaury'
import { type App } from 'vue'
-import type { EditorRunner } from 'enso-common/src/types'
import 'enso-dashboard/src/tailwind.css'
import { AsyncApp } from './asyncApp'
@@ -83,7 +83,7 @@ function main() {
const appRunner = lazyVueInReact(AsyncApp as any /* async VueComponent */, {
beforeVueAppMount: (app) => registerPlugins(app as App),
- }) as EditorRunner
+ }) as dashboard.GraphEditorRunner
dashboard.run({
appRunner,
diff --git a/app/gui2/stories/GraphEditor.story.vue b/app/gui2/stories/GraphEditor.story.vue
index 307e79bc833..2369cd89087 100644
--- a/app/gui2/stories/GraphEditor.story.vue
+++ b/app/gui2/stories/GraphEditor.story.vue
@@ -38,16 +38,17 @@ main =
/**
* Note: These props should be synced with the props in
- * `app/ide-desktop/lib/dashboard/src/authentication/src/components/app.tsx`.
- * We need this here, as the react component is not part of the dashboard and not usually available in the demo scenes.
- * Using this wrapper enables us to see toasts in the absence of the dashboard/React.
+ * `app/dashboard/src/App.tsx`.
+ * We need this here, as the React component is not part of the dashboard and not usually
+ * available in the demo scenes. Using this wrapper enables us to see toasts in the absence
+ * of the dashboard/React.
*/
const toastProps = reactive({
position: 'top-center',
theme: 'light',
closeOnClick: false,
draggable: false,
- toastClassName: 'text-sm leading-170 bg-frame-selected rounded-2xl backdrop-blur-3xl',
+ toastClassName: 'text-sm leading-cozy bg-selected-frame rounded-lg backdrop-blur-default',
limit: 3,
})
const WrappedToastContainer = createReactWrapper(ToastContainer, toastProps)
diff --git a/app/gui2/tsconfig.app.json b/app/gui2/tsconfig.app.json
index d26df049b8f..a26205c4faa 100644
--- a/app/gui2/tsconfig.app.json
+++ b/app/gui2/tsconfig.app.json
@@ -26,13 +26,7 @@
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"types": ["vitest/importMeta"],
- "paths": {
- "@/*": ["./src/*"]
- }
+ "paths": { "@/*": ["./src/*"] }
},
- "references": [
- {
- "path": "../ide-desktop/lib/dashboard/tsconfig.json"
- }
- ]
+ "references": [{ "path": "../dashboard" }]
}
diff --git a/app/gui2/tsconfig.json b/app/gui2/tsconfig.json
index b1c88e417dc..d5e03708b95 100644
--- a/app/gui2/tsconfig.json
+++ b/app/gui2/tsconfig.json
@@ -1,29 +1,13 @@
{
"files": [],
"references": [
- {
- "path": "../ide-desktop/lib/dashboard/tsconfig.json"
- },
- {
- "path": "./tsconfig.node.json"
- },
- {
- "path": "./tsconfig.app.json"
- },
- {
- "path": "./tsconfig.app.vitest.json"
- },
- {
- "path": "./tsconfig.server.json"
- },
- {
- "path": "./tsconfig.server.vitest.json"
- },
- {
- "path": "./tsconfig.story.json"
- },
- {
- "path": "./tsconfig.scripts.json"
- }
+ { "path": "../dashboard" },
+ { "path": "./tsconfig.node.json" },
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.app.vitest.json" },
+ { "path": "./tsconfig.server.json" },
+ { "path": "./tsconfig.server.vitest.json" },
+ { "path": "./tsconfig.story.json" },
+ { "path": "./tsconfig.scripts.json" }
]
}
diff --git a/app/gui2/tsconfig.story.json b/app/gui2/tsconfig.story.json
index 5e18a360a6e..2d4046f9de4 100644
--- a/app/gui2/tsconfig.story.json
+++ b/app/gui2/tsconfig.story.json
@@ -34,9 +34,5 @@
"@/*": ["./src/*"]
}
},
- "references": [
- {
- "path": "../ide-desktop/lib/dashboard/tsconfig.json"
- }
- ]
+ "references": [{ "path": "../dashboard" }]
}
diff --git a/app/gui2/vite.config.ts b/app/gui2/vite.config.ts
index 05b4e15cf41..0f5d14cabb3 100644
--- a/app/gui2/vite.config.ts
+++ b/app/gui2/vite.config.ts
@@ -31,7 +31,7 @@ export default defineConfig({
VueDevTools(),
vue(),
react({
- include: fileURLToPath(new URL('../ide-desktop/lib/dashboard/**/*.tsx', import.meta.url)),
+ include: fileURLToPath(new URL('../dashboard/**/*.tsx', import.meta.url)),
babel: { plugins: ['@babel/plugin-syntax-import-attributes'] },
}),
gatewayServer(),
@@ -74,10 +74,7 @@ export default defineConfig({
tailwindcss({
...tailwindConfig.default,
content: tailwindConfig.default.content.map((glob: string) =>
- glob.replace(
- /^[.][/]/,
- fileURLToPath(new URL('../ide-desktop/lib/dashboard/', import.meta.url)),
- ),
+ glob.replace(/^[.][/]/, fileURLToPath(new URL('../dashboard/', import.meta.url))),
),
}),
],
@@ -100,9 +97,7 @@ function gatewayServer(): Plugin {
}
async function projectManagerShim(): Promise {
- const module = await import(
- '../ide-desktop/lib/project-manager-shim/src/projectManagerShimMiddleware'
- )
+ const module = await import('./project-manager-shim-middleware')
return {
name: 'project-manager-shim',
configureServer(server) {
diff --git a/app/ide-desktop/client/build-info.ts b/app/ide-desktop/client/build-info.ts
new file mode 100644
index 00000000000..64ccdec7c16
--- /dev/null
+++ b/app/ide-desktop/client/build-info.ts
@@ -0,0 +1,4 @@
+/** @file A re-export of `build.json` to avoid breakage when moving the path of this module. */
+
+import BUILD_INFO from '../../../build.json' assert { type: 'json' }
+export default BUILD_INFO
diff --git a/app/ide-desktop/client/bundle.ts b/app/ide-desktop/client/bundle.ts
new file mode 100644
index 00000000000..0a3460c2f89
--- /dev/null
+++ b/app/ide-desktop/client/bundle.ts
@@ -0,0 +1,10 @@
+/** @file Script that bundles JS client code. */
+import * as esbuild from 'esbuild'
+
+import * as bundler from './esbuild-config'
+
+// ================
+// === Bundling ===
+// ================
+
+await esbuild.build(bundler.bundlerOptionsFromEnv())
diff --git a/app/ide-desktop/lib/client/dist.ts b/app/ide-desktop/client/dist.ts
similarity index 100%
rename from app/ide-desktop/lib/client/dist.ts
rename to app/ide-desktop/client/dist.ts
diff --git a/app/ide-desktop/lib/client/electron-builder-config.ts b/app/ide-desktop/client/electron-builder-config.ts
similarity index 99%
rename from app/ide-desktop/lib/client/electron-builder-config.ts
rename to app/ide-desktop/client/electron-builder-config.ts
index 62c4252f5d6..2c2859e49ab 100644
--- a/app/ide-desktop/lib/client/electron-builder-config.ts
+++ b/app/ide-desktop/client/electron-builder-config.ts
@@ -20,7 +20,7 @@ import * as paths from './paths'
import computeHashes from './tasks/computeHashes.mjs'
import signArchivesMacOs from './tasks/signArchivesMacOs'
-import BUILD_INFO from '../../../../build.json' assert { type: 'json' }
+import BUILD_INFO from './build-info'
// =============
// === Types ===
diff --git a/app/ide-desktop/lib/client/entitlements.mac.plist b/app/ide-desktop/client/entitlements.mac.plist
similarity index 100%
rename from app/ide-desktop/lib/client/entitlements.mac.plist
rename to app/ide-desktop/client/entitlements.mac.plist
diff --git a/app/ide-desktop/lib/client/esbuild-config.ts b/app/ide-desktop/client/esbuild-config.ts
similarity index 89%
rename from app/ide-desktop/lib/client/esbuild-config.ts
rename to app/ide-desktop/client/esbuild-config.ts
index 9eeee65ec64..eadc77228b4 100644
--- a/app/ide-desktop/lib/client/esbuild-config.ts
+++ b/app/ide-desktop/client/esbuild-config.ts
@@ -51,11 +51,11 @@ export function bundlerOptions(
/* eslint-disable @typescript-eslint/naming-convention */
outExtension: { '.js': '.cjs' },
define: {
- PROJECT_MANAGER_IN_BUNDLE_PATH: JSON.stringify(projectManagerInBundlePath),
- 'process.env.ELECTRON_DEV_MODE': JSON.stringify(String(devMode)),
- 'process.env.GUI_CONFIG_PATH': JSON.stringify(
- path.resolve('../../../gui2/vite.config.ts')
+ 'process.env.PROJECT_MANAGER_IN_BUNDLE_PATH': JSON.stringify(
+ projectManagerInBundlePath
),
+ 'process.env.ELECTRON_DEV_MODE': JSON.stringify(String(devMode)),
+ 'process.env.GUI_CONFIG_PATH': JSON.stringify(path.resolve('../gui2/vite.config.ts')),
},
/* eslint-enable @typescript-eslint/naming-convention */
sourcemap: true,
diff --git a/app/ide-desktop/lib/client/file-associations.ts b/app/ide-desktop/client/file-associations.ts
similarity index 100%
rename from app/ide-desktop/lib/client/file-associations.ts
rename to app/ide-desktop/client/file-associations.ts
diff --git a/app/ide-desktop/lib/client/package.json b/app/ide-desktop/client/package.json
similarity index 71%
rename from app/ide-desktop/lib/client/package.json
rename to app/ide-desktop/client/package.json
index 440011a71c8..092fc2e91cd 100644
--- a/app/ide-desktop/lib/client/package.json
+++ b/app/ide-desktop/client/package.json
@@ -17,17 +17,13 @@
"description": "Enso Data Processing Environment.",
"main": "index.cjs",
"dependencies": {
- "@types/mime-types": "^2.1.1",
- "@types/opener": "^1.4.0",
- "@types/tar": "^6.1.4",
- "@types/yargs": "^17.0.30",
"chalk": "^5.2.0",
"create-servers": "3.2.0",
"electron-is-dev": "^2.0.0",
- "enso-content-config": "workspace:*",
"mime-types": "^2.1.35",
"mkcert": "3.2.0",
"opener": "^1.5.2",
+ "semver": "^7.6.2",
"string-length": "^5.0.1",
"tar": "^6.2.0",
"yargs": "17.6.2"
@@ -35,10 +31,16 @@
"devDependencies": {
"@babel/plugin-syntax-import-attributes": "^7.24.7",
"@electron/notarize": "2.1.0",
+ "@types/mime-types": "^2.1.1",
"@types/node": "^20.11.21",
+ "@types/opener": "^1.4.0",
+ "@types/semver": "^7.5.8",
+ "@types/tar": "^6.1.4",
+ "@types/yargs": "^17.0.30",
"electron": "31.2.0",
"electron-builder": "^24.13.3",
"enso-common": "workspace:*",
+ "enso-dashboard": "workspace:*",
"enso-gui2": "workspace:*",
"enso-runner": "workspace:*",
"esbuild": "^0.19.3",
@@ -59,12 +61,10 @@
],
"scripts": {
"typecheck": "npm run --workspace=enso-gui2 compile-server && tsc --build",
- "start": "tsx start.ts",
"build": "tsx bundle.ts",
"dist": "tsx dist.ts",
- "watch": "tsx watch.ts",
- "watch:windows": "cross-env ENSO_BUILD_IDE=%LOCALAPPDATA%/Temp/enso/dist/ide ENSO_BUILD_PROJECT_MANAGER=%CD%/../../../../dist/backend ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH=bin/project-manager.exe ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION=0 tsx watch.ts",
- "watch:linux": "ENSO_BUILD_IDE=\"${ENSO_BUILD_IDE:-/tmp/enso/dist/ide}\" ENSO_BUILD_PROJECT_MANAGER=\"${ENSO_BUILD_PROJECT_MANAGER:-\"$(pwd)/../../../../dist/backend\"}\" ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH=\"${ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH:-bin/project-manager}\" ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION=\"${ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION:-0}\" tsx watch.ts \"$@\"",
- "watch:macos": "ENSO_BUILD_IDE=\"${ENSO_BUILD_IDE:-/tmp/enso/dist/ide}\" ENSO_BUILD_PROJECT_MANAGER=\"${ENSO_BUILD_PROJECT_MANAGER:-\"$(pwd)/../../../../dist/backend\"}\" ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH=\"${ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH:-bin/project-manager}\" ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION=\"${ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION:-0}\" tsx watch.ts \"$@\""
+ "watch:windows": "cross-env ENSO_BUILD_IDE=%LOCALAPPDATA%/Temp/enso/dist/ide ENSO_BUILD_PROJECT_MANAGER=%CD%/../../dist/backend ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH=bin/project-manager.exe ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION=0 tsx watch.ts",
+ "watch:linux": "ENSO_BUILD_IDE=\"${ENSO_BUILD_IDE:-/tmp/enso/dist/ide}\" ENSO_BUILD_PROJECT_MANAGER=\"${ENSO_BUILD_PROJECT_MANAGER:-\"$(pwd)/../../dist/backend\"}\" ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH=\"${ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH:-bin/project-manager}\" ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION=\"${ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION:-0}\" tsx watch.ts \"$@\"",
+ "watch:macos": "ENSO_BUILD_IDE=\"${ENSO_BUILD_IDE:-/tmp/enso/dist/ide}\" ENSO_BUILD_PROJECT_MANAGER=\"${ENSO_BUILD_PROJECT_MANAGER:-\"$(pwd)/../../dist/backend\"}\" ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH=\"${ENSO_BUILD_PROJECT_MANAGER_IN_BUNDLE_PATH:-bin/project-manager}\" ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION=\"${ENSO_BUILD_IDE_BUNDLED_ENGINE_VERSION:-0}\" tsx watch.ts \"$@\""
}
}
diff --git a/app/ide-desktop/lib/client/paths.ts b/app/ide-desktop/client/paths.ts
similarity index 87%
rename from app/ide-desktop/lib/client/paths.ts
rename to app/ide-desktop/client/paths.ts
index 7dff2adc4f8..b592947dc78 100644
--- a/app/ide-desktop/lib/client/paths.ts
+++ b/app/ide-desktop/client/paths.ts
@@ -15,11 +15,6 @@ export function getIdeDirectory(): string {
return buildUtils.requireEnv('ENSO_BUILD_IDE')
}
-/** Distribution directory for GUI. */
-export function getGuiDirectory(): string {
- return buildUtils.requireEnv('ENSO_BUILD_GUI')
-}
-
/** Path to the project manager bundle root. */
export function getProjectManagerBundlePath(): string {
return buildUtils.requireEnv('ENSO_BUILD_PROJECT_MANAGER')
diff --git a/app/ide-desktop/lib/client/src/authentication.ts b/app/ide-desktop/client/src/authentication.ts
similarity index 98%
rename from app/ide-desktop/lib/client/src/authentication.ts
rename to app/ide-desktop/client/src/authentication.ts
index 9b18e55c2c7..23aa2614d2f 100644
--- a/app/ide-desktop/lib/client/src/authentication.ts
+++ b/app/ide-desktop/client/src/authentication.ts
@@ -78,8 +78,9 @@ import * as electron from 'electron'
import opener from 'opener'
import * as common from 'enso-common'
-import * as contentConfig from 'enso-content-config'
+import type * as dashboard from 'enso-dashboard'
+import * as contentConfig from 'content-config'
import * as ipc from 'ipc'
import * as urlAssociations from 'url-associations'
@@ -118,7 +119,7 @@ export function initAuthentication(window: () => electron.BrowserWindow) {
// Listen for events to save the given user credentials to `~/.enso/credentials`.
electron.ipcMain.on(
ipc.Channel.saveAccessToken,
- (event, accessTokenPayload: SaveAccessTokenPayload | null) => {
+ (event, accessTokenPayload: dashboard.AccessToken | null) => {
event.preventDefault()
/** Home directory for the credentials file. */
diff --git a/app/ide-desktop/lib/client/src/bin/project-manager.ts b/app/ide-desktop/client/src/bin/project-manager.ts
similarity index 98%
rename from app/ide-desktop/lib/client/src/bin/project-manager.ts
rename to app/ide-desktop/client/src/bin/project-manager.ts
index 92d6558b9ee..12866d1855b 100644
--- a/app/ide-desktop/lib/client/src/bin/project-manager.ts
+++ b/app/ide-desktop/client/src/bin/project-manager.ts
@@ -4,7 +4,7 @@ import * as childProcess from 'node:child_process'
import * as fsSync from 'node:fs'
import * as util from 'node:util'
-import * as contentConfig from 'enso-content-config'
+import * as contentConfig from 'content-config'
import type * as config from 'config'
diff --git a/app/ide-desktop/lib/client/src/bin/server.ts b/app/ide-desktop/client/src/bin/server.ts
similarity index 99%
rename from app/ide-desktop/lib/client/src/bin/server.ts
rename to app/ide-desktop/client/src/bin/server.ts
index 324e5792112..707486894ae 100644
--- a/app/ide-desktop/lib/client/src/bin/server.ts
+++ b/app/ide-desktop/client/src/bin/server.ts
@@ -14,11 +14,11 @@ import createServer from 'create-servers'
import * as common from 'enso-common'
import GLOBAL_CONFIG from 'enso-common/src/config.json' assert { type: 'json' }
-import * as contentConfig from 'enso-content-config'
import * as ydocServer from 'enso-gui2/ydoc-server'
import * as projectManagement from 'project-management'
-import * as paths from '../paths'
+import * as contentConfig from 'content-config'
+import * as paths from 'paths'
const logger = contentConfig.logger
diff --git a/app/ide-desktop/lib/content-config/src/config.json b/app/ide-desktop/client/src/config.json
similarity index 100%
rename from app/ide-desktop/lib/content-config/src/config.json
rename to app/ide-desktop/client/src/config.json
diff --git a/app/ide-desktop/lib/client/src/config.ts b/app/ide-desktop/client/src/config.ts
similarity index 99%
rename from app/ide-desktop/lib/client/src/config.ts
rename to app/ide-desktop/client/src/config.ts
index f01c603e776..16fdf9d7e92 100644
--- a/app/ide-desktop/lib/client/src/config.ts
+++ b/app/ide-desktop/client/src/config.ts
@@ -3,8 +3,7 @@
import chalk from 'chalk'
-import * as contentConfig from 'enso-content-config'
-
+import * as contentConfig from 'content-config'
import * as naming from 'naming'
import * as paths from 'paths'
diff --git a/app/ide-desktop/lib/client/src/config/parser.ts b/app/ide-desktop/client/src/config/parser.ts
similarity index 99%
rename from app/ide-desktop/lib/client/src/config/parser.ts
rename to app/ide-desktop/client/src/config/parser.ts
index 2f878161d7f..3f37f2f654a 100644
--- a/app/ide-desktop/lib/client/src/config/parser.ts
+++ b/app/ide-desktop/client/src/config/parser.ts
@@ -6,12 +6,11 @@ import stringLength from 'string-length'
// eslint-disable-next-line no-restricted-syntax
import yargs, { type Options } from 'yargs'
-import * as contentConfig from 'enso-content-config'
-
import * as config from 'config'
+import * as contentConfig from 'content-config'
import * as fileAssociations from 'file-associations'
import * as naming from 'naming'
-import BUILD_INFO from '../../../../../../build.json' assert { type: 'json' }
+import BUILD_INFO from '../../build-info'
const logger = contentConfig.logger
diff --git a/app/ide-desktop/lib/content-config/src/index.ts b/app/ide-desktop/client/src/content-config.ts
similarity index 95%
rename from app/ide-desktop/lib/content-config/src/index.ts
rename to app/ide-desktop/client/src/content-config.ts
index 052b9d1f36e..982b4bb5c94 100644
--- a/app/ide-desktop/lib/content-config/src/index.ts
+++ b/app/ide-desktop/client/src/content-config.ts
@@ -3,7 +3,7 @@
import * as semver from 'semver'
import * as linkedDist from 'enso-runner/src/runner'
-import BUILD_INFO from '../../../../../build.json' assert { type: 'json' }
+import BUILD_INFO from '../build-info'
// Aliases with the same name as the original.
// eslint-disable-next-line no-restricted-syntax
diff --git a/app/ide-desktop/lib/client/src/debug.ts b/app/ide-desktop/client/src/debug.ts
similarity index 95%
rename from app/ide-desktop/lib/client/src/debug.ts
rename to app/ide-desktop/client/src/debug.ts
index bdca2e08b68..d471de5fdb4 100644
--- a/app/ide-desktop/lib/client/src/debug.ts
+++ b/app/ide-desktop/client/src/debug.ts
@@ -2,7 +2,7 @@
import * as buildUtils from 'enso-common/src/buildUtils'
-import BUILD_INFO from '../../../../../build.json' assert { type: 'json' }
+import BUILD_INFO from '../build-info'
// ==================
// === Debug Info ===
diff --git a/app/ide-desktop/lib/client/src/desktop-environment.ts b/app/ide-desktop/client/src/desktop-environment.ts
similarity index 100%
rename from app/ide-desktop/lib/client/src/desktop-environment.ts
rename to app/ide-desktop/client/src/desktop-environment.ts
diff --git a/app/ide-desktop/lib/client/src/detect.ts b/app/ide-desktop/client/src/detect.ts
similarity index 100%
rename from app/ide-desktop/lib/client/src/detect.ts
rename to app/ide-desktop/client/src/detect.ts
diff --git a/app/ide-desktop/lib/client/src/file-associations.ts b/app/ide-desktop/client/src/file-associations.ts
similarity index 98%
rename from app/ide-desktop/lib/client/src/file-associations.ts
rename to app/ide-desktop/client/src/file-associations.ts
index 2f11a3ec032..582d78ffaa8 100644
--- a/app/ide-desktop/lib/client/src/file-associations.ts
+++ b/app/ide-desktop/client/src/file-associations.ts
@@ -12,11 +12,11 @@ import * as electron from 'electron'
import electronIsDev from 'electron-is-dev'
import * as common from 'enso-common'
-import * as contentConfig from 'enso-content-config'
-import type * as clientConfig from './config'
+import type * as clientConfig from 'config'
+import * as contentConfig from 'content-config'
+import * as project from 'project-management'
import * as fileAssociations from '../file-associations'
-import * as project from './project-management'
const logger = contentConfig.logger
diff --git a/app/ide-desktop/lib/types/globals.d.ts b/app/ide-desktop/client/src/globals.d.ts
similarity index 74%
rename from app/ide-desktop/lib/types/globals.d.ts
rename to app/ide-desktop/client/src/globals.d.ts
index 805f9881ea4..58ceeb35646 100644
--- a/app/ide-desktop/lib/types/globals.d.ts
+++ b/app/ide-desktop/client/src/globals.d.ts
@@ -1,12 +1,11 @@
/** @file Globals defined outside of TypeScript files.
* These are from variables defined at build time, environment variables,
* monkeypatching on `window` and generated code. */
-///
+import type * as dashboard from 'enso-dashboard'
// This file is being imported for its types.
-// prettier-ignore
-// eslint-disable-next-line no-restricted-syntax, @typescript-eslint/consistent-type-imports
-import * as buildJson from './../../build.json' assert {type: 'json'}
+// eslint-disable-next-line no-restricted-syntax
+import * as buildJson from './../../build.json' assert { type: 'json' }
// =============
// === Types ===
@@ -57,7 +56,7 @@ interface AuthenticationApi {
* via a deep link. See `setDeepLinkHandler` for details. */
readonly setDeepLinkHandler: (callback: (url: string) => void) => void
/** Saves the access token to a file. */
- readonly saveAccessToken: (accessToken: SaveAccessTokenPayload | null) => void
+ readonly saveAccessToken: (accessToken: dashboard.AccessToken | null) => void
}
// ======================
@@ -181,46 +180,13 @@ declare global {
// @ts-expect-error The index signature is intentional to disallow unknown env vars.
readonly APPLETEAMID?: string
// @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_BUILD_ICONS?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
readonly ENSO_BUILD_ELECTRON_BUILDER_CONFIG?: string
// @ts-expect-error The index signature is intentional to disallow unknown env vars.
readonly npm_package_name?: string
-
- // === Cloud environment variables ===
-
// @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_REDIRECT?: string
- // When unset, the `.env` loader tries to load `.env` rather than `..env`.
- // Set to the empty string to load `.env`.
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_ENVIRONMENT: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_API_URL?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_CHAT_URL?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_SENTRY_DSN?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_STRIPE_KEY?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_COGNITO_USER_POOL_ID?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_COGNITO_USER_POOL_WEB_CLIENT_ID?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_COGNITO_DOMAIN?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_COGNITO_REGION?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_GOOGLE_ANALYTICS_TAG?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_DASHBOARD_VERSION?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_DASHBOARD_COMMIT_HASH?: string
+ readonly PROJECT_MANAGER_IN_BUNDLE_PATH: string
// @ts-expect-error The index signature is intentional to disallow unknown env vars.
readonly ENSO_SUPPORTS_VIBRANCY?: string
- // @ts-expect-error The index signature is intentional to disallow unknown env vars.
- readonly ENSO_CLOUD_ENSO_HOST?: string
// === E2E test variables ===
@@ -244,6 +210,4 @@ declare global {
// These are used in other files (because they're globals)
/* eslint-disable @typescript-eslint/naming-convention */
const BUILD_INFO: buildJson.BuildInfo
- const PROJECT_MANAGER_IN_BUNDLE_PATH: string
- const IS_VITE: boolean
}
diff --git a/app/ide-desktop/lib/client/src/index.ts b/app/ide-desktop/client/src/index.ts
similarity index 99%
rename from app/ide-desktop/lib/client/src/index.ts
rename to app/ide-desktop/client/src/index.ts
index 0de694cb5ba..29c23e4401e 100644
--- a/app/ide-desktop/lib/client/src/index.ts
+++ b/app/ide-desktop/client/src/index.ts
@@ -17,11 +17,11 @@ import * as portfinder from 'portfinder'
import * as common from 'enso-common'
import * as buildUtils from 'enso-common/src/buildUtils'
import GLOBAL_CONFIG from 'enso-common/src/config.json' assert { type: 'json' }
-import * as contentConfig from 'enso-content-config'
import * as authentication from 'authentication'
import * as config from 'config'
import * as configParser from 'config/parser'
+import * as contentConfig from 'content-config'
import * as debug from 'debug'
import * as detect from 'detect'
import * as fileAssociations from 'file-associations'
diff --git a/app/ide-desktop/lib/client/src/ipc.ts b/app/ide-desktop/client/src/ipc.ts
similarity index 100%
rename from app/ide-desktop/lib/client/src/ipc.ts
rename to app/ide-desktop/client/src/ipc.ts
diff --git a/app/ide-desktop/lib/client/src/log.ts b/app/ide-desktop/client/src/log.ts
similarity index 98%
rename from app/ide-desktop/lib/client/src/log.ts
rename to app/ide-desktop/client/src/log.ts
index 249cb21978f..0384c4a4329 100644
--- a/app/ide-desktop/lib/client/src/log.ts
+++ b/app/ide-desktop/client/src/log.ts
@@ -11,7 +11,7 @@ import * as pathModule from 'node:path'
import * as linkedDist from 'enso-runner/src/runner'
-import * as contentConfig from 'enso-content-config'
+import * as contentConfig from 'content-config'
import * as paths from 'paths'
// ================
diff --git a/app/ide-desktop/client/src/modules.d.ts b/app/ide-desktop/client/src/modules.d.ts
new file mode 100644
index 00000000000..57cb2b297d9
--- /dev/null
+++ b/app/ide-desktop/client/src/modules.d.ts
@@ -0,0 +1,52 @@
+/** @file Type definitions for modules that currently lack typings on DefinitelyTyped.
+ *
+ * This file MUST NOT `export {}` so that the modules are visible to other files. */
+
+// Required because this is a build artifact, which does not exist on a clean repository.
+declare module '*/build.json' {
+ /** Build metadata generated by the build CLI. */
+ export interface BuildInfo {
+ readonly commit: string
+ readonly version: string
+ readonly engineVersion: string
+ readonly name: string
+ }
+
+ const BUILD_INFO: BuildInfo
+ export default BUILD_INFO
+}
+
+declare module 'create-servers' {
+ import type * as http from 'node:http'
+ import type * as https from 'node:https'
+
+ /** Configuration options for `create-servers`. */
+ interface CreateServersOptions {
+ readonly http?: number
+ readonly handler: http.RequestListener
+ // eslint-disable-next-line no-restricted-syntax
+ readonly https?: {
+ readonly port: number
+ readonly key: string
+ readonly cert: string
+ }
+ }
+
+ /** An error passed to a callback when a HTTP request fails. */
+ interface HttpError {
+ readonly http: string
+ }
+
+ /** Created server instances of various types. */
+ interface CreatedServers {
+ readonly http?: http.Server
+ readonly https?: https.Server
+ }
+
+ export default function (
+ option: CreateServersOptions,
+ // The types come from a third-party API and cannot be changed.
+ // eslint-disable-next-line no-restricted-syntax
+ handler: (err: HttpError | undefined, servers: CreatedServers) => void
+ ): unknown
+}
diff --git a/app/ide-desktop/lib/client/src/naming.ts b/app/ide-desktop/client/src/naming.ts
similarity index 100%
rename from app/ide-desktop/lib/client/src/naming.ts
rename to app/ide-desktop/client/src/naming.ts
diff --git a/app/ide-desktop/lib/client/src/paths.ts b/app/ide-desktop/client/src/paths.ts
similarity index 97%
rename from app/ide-desktop/lib/client/src/paths.ts
rename to app/ide-desktop/client/src/paths.ts
index e247b4ceac4..a42606cbebd 100644
--- a/app/ide-desktop/lib/client/src/paths.ts
+++ b/app/ide-desktop/client/src/paths.ts
@@ -36,7 +36,7 @@ export const PROJECT_MANAGER_PATH = path.join(
RESOURCES_PATH,
paths.PROJECT_MANAGER_BUNDLE,
// Placeholder for a bundler-provided define.
- PROJECT_MANAGER_IN_BUNDLE_PATH
+ process.env.PROJECT_MANAGER_IN_BUNDLE_PATH
)
/** Relative path of Enso Project package metadata relative to the project root. */
diff --git a/app/ide-desktop/lib/client/src/preload.ts b/app/ide-desktop/client/src/preload.ts
similarity index 98%
rename from app/ide-desktop/lib/client/src/preload.ts
rename to app/ide-desktop/client/src/preload.ts
index 869a391e042..d2112a9a736 100644
--- a/app/ide-desktop/lib/client/src/preload.ts
+++ b/app/ide-desktop/client/src/preload.ts
@@ -5,6 +5,8 @@
import * as electron from 'electron'
+import type * as dashboard from 'enso-dashboard'
+
import * as debug from 'debug'
import * as ipc from 'ipc'
import type * as projectManagement from 'project-management'
@@ -115,7 +117,7 @@ exposeInMainWorld(AUTHENTICATION_API_KEY, {
*
* The backend doesn't have access to Electron's `localStorage` so we need to save access token
* to a file. Then the token will be used to sign cloud API requests. */
- saveAccessToken: (accessTokenPayload: SaveAccessTokenPayload | null) => {
+ saveAccessToken: (accessTokenPayload: dashboard.AccessToken | null) => {
electron.ipcRenderer.send(ipc.Channel.saveAccessToken, accessTokenPayload)
},
})
diff --git a/app/ide-desktop/lib/client/src/project-management.ts b/app/ide-desktop/client/src/project-management.ts
similarity index 99%
rename from app/ide-desktop/lib/client/src/project-management.ts
rename to app/ide-desktop/client/src/project-management.ts
index 1ebf97161b7..d17b058b67f 100644
--- a/app/ide-desktop/lib/client/src/project-management.ts
+++ b/app/ide-desktop/client/src/project-management.ts
@@ -17,6 +17,7 @@ import * as tar from 'tar'
import * as common from 'enso-common'
import * as buildUtils from 'enso-common/src/buildUtils'
+
import * as desktopEnvironment from 'desktop-environment'
const logger = console
diff --git a/app/ide-desktop/lib/client/src/security.ts b/app/ide-desktop/client/src/security.ts
similarity index 100%
rename from app/ide-desktop/lib/client/src/security.ts
rename to app/ide-desktop/client/src/security.ts
diff --git a/app/ide-desktop/lib/client/src/url-associations.ts b/app/ide-desktop/client/src/url-associations.ts
similarity index 98%
rename from app/ide-desktop/lib/client/src/url-associations.ts
rename to app/ide-desktop/client/src/url-associations.ts
index 13ba6ca296c..6e4d265cf27 100644
--- a/app/ide-desktop/lib/client/src/url-associations.ts
+++ b/app/ide-desktop/client/src/url-associations.ts
@@ -4,7 +4,8 @@ import * as electron from 'electron'
import electronIsDev from 'electron-is-dev'
import * as common from 'enso-common'
-import * as contentConfig from 'enso-content-config'
+
+import * as contentConfig from 'content-config'
const logger = contentConfig.logger
diff --git a/app/ide-desktop/lib/client/tasks/computeHashes.mjs b/app/ide-desktop/client/tasks/computeHashes.mjs
similarity index 100%
rename from app/ide-desktop/lib/client/tasks/computeHashes.mjs
rename to app/ide-desktop/client/tasks/computeHashes.mjs
diff --git a/app/ide-desktop/lib/client/tasks/signArchivesMacOs.ts b/app/ide-desktop/client/tasks/signArchivesMacOs.ts
similarity index 100%
rename from app/ide-desktop/lib/client/tasks/signArchivesMacOs.ts
rename to app/ide-desktop/client/tasks/signArchivesMacOs.ts
diff --git a/app/ide-desktop/client/tsconfig.json b/app/ide-desktop/client/tsconfig.json
new file mode 100644
index 00000000000..86412787b11
--- /dev/null
+++ b/app/ide-desktop/client/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "baseUrl": "./src",
+ "esModuleInterop": true
+ },
+ "include": [
+ ".",
+ "../content",
+ "../types",
+ "../../build.json",
+ "src/config.json"
+ ],
+ "references": [
+ { "path": "../../gui2/tsconfig.server.json" },
+ { "path": "../../dashboard" }
+ ]
+}
diff --git a/app/ide-desktop/lib/client/watch.ts b/app/ide-desktop/client/watch.ts
similarity index 100%
rename from app/ide-desktop/lib/client/watch.ts
rename to app/ide-desktop/client/watch.ts
diff --git a/app/ide-desktop/lib/common/package.json b/app/ide-desktop/common/package.json
similarity index 100%
rename from app/ide-desktop/lib/common/package.json
rename to app/ide-desktop/common/package.json
diff --git a/app/ide-desktop/lib/common/src/appConfig.d.ts b/app/ide-desktop/common/src/appConfig.d.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/appConfig.d.ts
rename to app/ide-desktop/common/src/appConfig.d.ts
diff --git a/app/ide-desktop/lib/common/src/appConfig.js b/app/ide-desktop/common/src/appConfig.js
similarity index 85%
rename from app/ide-desktop/lib/common/src/appConfig.js
rename to app/ide-desktop/common/src/appConfig.js
index 3570e81ad06..cf696ba7b38 100644
--- a/app/ide-desktop/lib/common/src/appConfig.js
+++ b/app/ide-desktop/common/src/appConfig.js
@@ -16,15 +16,14 @@ export async function readEnvironmentFromFile() {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const isProduction = environment == null || environment === '' || environment === 'production'
const fileName = isProduction ? '.env' : `.${environment}.env`
- const filePath = path.join(url.fileURLToPath(new URL('../../..', import.meta.url)), fileName)
- const expectedKeys = Object.keys(DUMMY_DEFINES).map(key => key.replace(/^process[.]env[.]/, ''))
- /** @type {string[]} */
- const missingKeys = []
- for (const key of expectedKeys) {
- if (!(key in process.env)) {
- missingKeys.push(key)
+ const filePath = path.join(url.fileURLToPath(new URL('../..', import.meta.url)), fileName)
+ const buildInfo = await (async () => {
+ try {
+ return await import('../../../../build.json', { assert: { type: 'json' } })
+ } catch {
+ return { commit: '', version: '', engineVersion: '', name: '' }
}
- }
+ })()
try {
const file = await fs.readFile(filePath, { encoding: 'utf-8' })
// eslint-disable-next-line jsdoc/valid-types
@@ -48,18 +47,25 @@ export async function readEnvironmentFromFile() {
if (!isProduction || entries.length > 0) {
Object.assign(process.env, variables)
}
- const buildInfo = await (async () => {
- try {
- return await import('../../../../../build.json', { type: 'json' })
- } catch {
- return { commit: '', version: '', engineVersion: '', name: '' }
- }
- })()
// @ts-expect-error This is the only file where `process.env` should be written to.
process.env.ENSO_CLOUD_DASHBOARD_VERSION ??= buildInfo.version
// @ts-expect-error This is the only file where `process.env` should be written to.
process.env.ENSO_CLOUD_DASHBOARD_COMMIT_HASH ??= buildInfo.commit
} catch (error) {
+ // @ts-expect-error This is the only file where `process.env` should be written to.
+ process.env.ENSO_CLOUD_DASHBOARD_VERSION ??= buildInfo.version
+ // @ts-expect-error This is the only file where `process.env` should be written to.
+ process.env.ENSO_CLOUD_DASHBOARD_COMMIT_HASH ??= buildInfo.commit
+ const expectedKeys = Object.keys(DUMMY_DEFINES)
+ .map(key => key.replace(/^process[.]env[.]/, ''))
+ .filter(key => key !== 'NODE_ENV')
+ /** @type {string[]} */
+ const missingKeys = []
+ for (const key of expectedKeys) {
+ if (!(key in process.env)) {
+ missingKeys.push(key)
+ }
+ }
if (missingKeys.length !== 0) {
console.warn('Could not load `.env` file; disabling cloud backend.')
console.warn(`Missing keys: ${missingKeys.map(key => `'${key}'`).join(', ')}`)
diff --git a/app/ide-desktop/lib/common/src/backendQuery.ts b/app/ide-desktop/common/src/backendQuery.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/backendQuery.ts
rename to app/ide-desktop/common/src/backendQuery.ts
diff --git a/app/ide-desktop/lib/common/src/buildUtils.d.ts b/app/ide-desktop/common/src/buildUtils.d.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/buildUtils.d.ts
rename to app/ide-desktop/common/src/buildUtils.d.ts
diff --git a/app/ide-desktop/lib/common/src/buildUtils.js b/app/ide-desktop/common/src/buildUtils.js
similarity index 100%
rename from app/ide-desktop/lib/common/src/buildUtils.js
rename to app/ide-desktop/common/src/buildUtils.js
diff --git a/app/ide-desktop/lib/common/src/config.json b/app/ide-desktop/common/src/config.json
similarity index 100%
rename from app/ide-desktop/lib/common/src/config.json
rename to app/ide-desktop/common/src/config.json
diff --git a/app/ide-desktop/lib/common/src/detect.ts b/app/ide-desktop/common/src/detect.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/detect.ts
rename to app/ide-desktop/common/src/detect.ts
diff --git a/app/ide-desktop/lib/common/src/gtag.ts b/app/ide-desktop/common/src/gtag.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/gtag.ts
rename to app/ide-desktop/common/src/gtag.ts
diff --git a/app/ide-desktop/lib/common/src/index.d.ts b/app/ide-desktop/common/src/index.d.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/index.d.ts
rename to app/ide-desktop/common/src/index.d.ts
diff --git a/app/ide-desktop/lib/common/src/index.js b/app/ide-desktop/common/src/index.js
similarity index 100%
rename from app/ide-desktop/lib/common/src/index.js
rename to app/ide-desktop/common/src/index.js
diff --git a/app/ide-desktop/lib/common/src/load.ts b/app/ide-desktop/common/src/load.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/load.ts
rename to app/ide-desktop/common/src/load.ts
diff --git a/app/ide-desktop/lib/common/src/queryClient.ts b/app/ide-desktop/common/src/queryClient.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/queryClient.ts
rename to app/ide-desktop/common/src/queryClient.ts
diff --git a/app/ide-desktop/lib/common/src/services/Backend.ts b/app/ide-desktop/common/src/services/Backend.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/services/Backend.ts
rename to app/ide-desktop/common/src/services/Backend.ts
diff --git a/app/ide-desktop/lib/common/src/text/english.json b/app/ide-desktop/common/src/text/english.json
similarity index 100%
rename from app/ide-desktop/lib/common/src/text/english.json
rename to app/ide-desktop/common/src/text/english.json
diff --git a/app/ide-desktop/lib/common/src/text/index.ts b/app/ide-desktop/common/src/text/index.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/text/index.ts
rename to app/ide-desktop/common/src/text/index.ts
diff --git a/app/ide-desktop/lib/common/src/utilities/data/array.ts b/app/ide-desktop/common/src/utilities/data/array.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/utilities/data/array.ts
rename to app/ide-desktop/common/src/utilities/data/array.ts
diff --git a/app/ide-desktop/lib/common/src/utilities/data/dateTime.ts b/app/ide-desktop/common/src/utilities/data/dateTime.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/utilities/data/dateTime.ts
rename to app/ide-desktop/common/src/utilities/data/dateTime.ts
diff --git a/app/ide-desktop/lib/common/src/utilities/data/newtype.ts b/app/ide-desktop/common/src/utilities/data/newtype.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/utilities/data/newtype.ts
rename to app/ide-desktop/common/src/utilities/data/newtype.ts
diff --git a/app/ide-desktop/lib/common/src/utilities/data/object.ts b/app/ide-desktop/common/src/utilities/data/object.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/utilities/data/object.ts
rename to app/ide-desktop/common/src/utilities/data/object.ts
diff --git a/app/ide-desktop/lib/common/src/utilities/permissions.ts b/app/ide-desktop/common/src/utilities/permissions.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/utilities/permissions.ts
rename to app/ide-desktop/common/src/utilities/permissions.ts
diff --git a/app/ide-desktop/lib/common/src/utilities/uniqueString.ts b/app/ide-desktop/common/src/utilities/uniqueString.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/utilities/uniqueString.ts
rename to app/ide-desktop/common/src/utilities/uniqueString.ts
diff --git a/app/ide-desktop/lib/common/src/vueQuery.ts b/app/ide-desktop/common/src/vueQuery.ts
similarity index 100%
rename from app/ide-desktop/lib/common/src/vueQuery.ts
rename to app/ide-desktop/common/src/vueQuery.ts
diff --git a/app/ide-desktop/lib/common/tsconfig.json b/app/ide-desktop/common/tsconfig.json
similarity index 100%
rename from app/ide-desktop/lib/common/tsconfig.json
rename to app/ide-desktop/common/tsconfig.json
diff --git a/app/ide-desktop/lib/icons/package.json b/app/ide-desktop/icons/package.json
similarity index 91%
rename from app/ide-desktop/lib/icons/package.json
rename to app/ide-desktop/icons/package.json
index e9cc8b7fb27..79da00fded2 100644
--- a/app/ide-desktop/lib/icons/package.json
+++ b/app/ide-desktop/icons/package.json
@@ -1,11 +1,12 @@
{
"name": "enso-icons",
+ "type": "module",
"version": "1.0.0",
"author": {
"name": "Enso Team",
"email": "contact@enso.org"
},
- "homepage": "https://github.com/enso-org/enso/tree/develop/app/ide-desktop/lib/icons",
+ "homepage": "https://github.com/enso-org/enso/tree/develop/app/icons",
"repository": {
"type": "git",
"url": "git@github.com:enso-org/enso.git"
@@ -21,6 +22,5 @@
"to-ico": "^1.1.5",
"@types/sharp": "^0.31.1",
"@types/to-ico": "^1.1.1"
- },
- "type": "module"
+ }
}
diff --git a/app/ide-desktop/lib/icons/src/index.js b/app/ide-desktop/icons/src/index.js
similarity index 99%
rename from app/ide-desktop/lib/icons/src/index.js
rename to app/ide-desktop/icons/src/index.js
index 4ac8b9a9b0a..11266587185 100644
--- a/app/ide-desktop/lib/icons/src/index.js
+++ b/app/ide-desktop/icons/src/index.js
@@ -211,6 +211,7 @@ async function genIcons(outputDir) {
/** Main entry function. */
async function main() {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const outputDir = process.env.ENSO_BUILD_ICONS ?? process.argv[2]
if (outputDir == null) {
const script = process.env.npm_package_name ?? url.fileURLToPath(import.meta.url)
diff --git a/app/ide-desktop/lib/assets/package.json b/app/ide-desktop/lib/assets/package.json
deleted file mode 100644
index 8cca4df267a..00000000000
--- a/app/ide-desktop/lib/assets/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "enso-assets",
- "type": "module",
- "version": "1.0.0",
- "author": {
- "name": "Enso Team",
- "email": "contact@enso.org"
- },
- "homepage": "https://github.com/enso-org/enso/tree/develop/app/ide-desktop/lib/assets",
- "repository": {
- "type": "git",
- "url": "git@github.com:enso-org/enso.git"
- },
- "bugs": {
- "url": "https://github.com/enso-org/enso/issues"
- }
-}
diff --git a/app/ide-desktop/lib/client/bundle.ts b/app/ide-desktop/lib/client/bundle.ts
deleted file mode 100644
index 4cace0082e7..00000000000
--- a/app/ide-desktop/lib/client/bundle.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/** @file Script that bundles JS client code. */
-
-import * as path from 'node:path'
-import * as url from 'node:url'
-
-import * as esbuild from 'esbuild'
-
-import * as bundler from './esbuild-config'
-import * as dashboardBundler from '../dashboard/esbuild-config'
-
-// =================
-// === Constants ===
-// =================
-
-export const THIS_PATH = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)))
-
-// ================
-// === Bundling ===
-// ================
-
-// The dashboard bundler bundles `tailwind.css`.
-const DASHBOARD_BUNDLER_OPTIONS = dashboardBundler.bundleOptions()
-await esbuild.build(DASHBOARD_BUNDLER_OPTIONS)
-const BUNDLER_OPTIONS = bundler.bundlerOptionsFromEnv()
-await esbuild.build(BUNDLER_OPTIONS)
diff --git a/app/ide-desktop/lib/client/start.ts b/app/ide-desktop/lib/client/start.ts
deleted file mode 100644
index 1bca4014032..00000000000
--- a/app/ide-desktop/lib/client/start.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-/** @file This script starts the IDE using the Electron executable. */
-
-import * as childProcess from 'node:child_process'
-import * as fs from 'node:fs/promises'
-import * as path from 'node:path'
-
-import * as esbuild from 'esbuild'
-
-import * as esbuildConfig from './esbuild-config'
-import * as paths from './paths'
-
-// =================
-// === Constants ===
-// =================
-
-const GUI_PATH = path.resolve(paths.getGuiDirectory())
-const IDE_PATH = paths.getIdeDirectory()
-const PROJECT_MANAGER_BUNDLE = paths.getProjectManagerBundlePath()
-
-// =================
-// === Start IDE ===
-// =================
-
-const SCRIPT_ARGS = process.argv.slice(2)
-console.log('Script arguments:', ...SCRIPT_ARGS.map(arg => JSON.stringify(arg)))
-
-console.log('Cleaning IDE dist directory.')
-await fs.rm(IDE_PATH, { recursive: true, force: true })
-await fs.mkdir(IDE_PATH, { recursive: true })
-
-console.log('Bundling client.')
-const BUNDLER_OPTIONS = esbuildConfig.bundlerOptionsFromEnv()
-BUNDLER_OPTIONS.outdir = path.resolve(IDE_PATH)
-await esbuild.build(BUNDLER_OPTIONS)
-
-console.log('Linking GUI files.')
-await fs.symlink(path.join(GUI_PATH, 'assets'), path.join(IDE_PATH, 'assets'), 'dir')
-
-console.log('Linking Project Manager files.')
-await fs.symlink(PROJECT_MANAGER_BUNDLE, path.join(IDE_PATH, paths.PROJECT_MANAGER_BUNDLE), 'dir')
-
-console.log('Spawning Electron process.')
-const ELECTRON_ARGS = [path.join(IDE_PATH, 'index.cjs'), '--', ...SCRIPT_ARGS]
-const ELECTRON_PROCESS = childProcess.spawn('electron', ELECTRON_ARGS, {
- stdio: 'inherit',
- shell: true,
-})
-
-// Wait till process finished.
-const CODE = await new Promise((resolve, reject) => {
- ELECTRON_PROCESS.on('close', resolve)
- ELECTRON_PROCESS.on('error', reject)
-})
-console.log(`Electron process finished. Exit code: ${CODE}.`)
diff --git a/app/ide-desktop/lib/client/tsconfig.json b/app/ide-desktop/lib/client/tsconfig.json
deleted file mode 100644
index fba8205bba0..00000000000
--- a/app/ide-desktop/lib/client/tsconfig.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "baseUrl": "./src",
- "esModuleInterop": true
- },
- "include": [".", "../content", "../types", "../../../../build.json"],
- "references": [
- { "path": "../../../gui2/tsconfig.server.json" },
- { "path": "../dashboard" }
- ]
-}
diff --git a/app/ide-desktop/lib/common/src/types.d.ts b/app/ide-desktop/lib/common/src/types.d.ts
deleted file mode 100644
index 223d78404eb..00000000000
--- a/app/ide-desktop/lib/common/src/types.d.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/** @file Interfaces common to multiple modules. */
-import type * as React from 'react'
-
-import type Backend from './services/Backend'
-
-// ======================================
-// === Globally accessible interfaces ===
-// ======================================
-
-/** A configuration in which values may be strings or nested configurations. */
-interface StringConfig {
- readonly [key: string]: StringConfig | string
-}
-
-/** Props for GUI editor root component. */
-interface EditorProps {
- readonly config: StringConfig | null
- readonly projectId: string
- readonly hidden: boolean
- readonly ignoreParamsRegex?: RegExp
- readonly logEvent: (
- message: string,
- projectId?: string | null,
- metadata?: object | null
- ) => void
- readonly renameProject: (newName: string) => void
- readonly backend: Backend | null
-}
-
-/** The value passed from the entrypoint to the dashboard, which enables the dashboard to
- * open a new IDE instance. */
-type EditorRunner = React.ComponentType
diff --git a/app/ide-desktop/lib/content-config/package.json b/app/ide-desktop/lib/content-config/package.json
deleted file mode 100644
index 2ba25838007..00000000000
--- a/app/ide-desktop/lib/content-config/package.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name": "enso-content-config",
- "version": "1.0.0",
- "type": "module",
- "main": "src/index.ts",
- "author": {
- "name": "Enso Team",
- "email": "contact@enso.org"
- },
- "homepage": "https://github.com/enso-org/enso",
- "repository": {
- "type": "git",
- "url": "git@github.com:enso-org/enso.git"
- },
- "bugs": {
- "url": "https://github.com/enso-org/enso/issues"
- },
- "dependencies": {
- "@types/semver": "^7.5.8",
- "semver": "^7.6.2",
- "enso-runner": "workspace:*"
- }
-}
diff --git a/app/ide-desktop/lib/content-config/tsconfig.json b/app/ide-desktop/lib/content-config/tsconfig.json
deleted file mode 100644
index ca45348e274..00000000000
--- a/app/ide-desktop/lib/content-config/tsconfig.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "include": ["../types", "../../../../build.json", ".", "src/config.json"]
-}
diff --git a/app/ide-desktop/lib/dashboard/assets.d.ts b/app/ide-desktop/lib/dashboard/assets.d.ts
deleted file mode 100644
index 3cc6dc166b8..00000000000
--- a/app/ide-desktop/lib/dashboard/assets.d.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/** @file Blanket module declarations for asset file imports. */
-
-declare module 'enso-assets/*.svg' {
- const VALUE: string
- export default VALUE
-}
-
-declare module 'enso-assets/*.png' {
- const VALUE: string
- export default VALUE
-}
diff --git a/app/ide-desktop/lib/dashboard/esbuild-config.ts b/app/ide-desktop/lib/dashboard/esbuild-config.ts
deleted file mode 100644
index 5da657a7e47..00000000000
--- a/app/ide-desktop/lib/dashboard/esbuild-config.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-/** @file Configuration for the esbuild bundler and build/watch commands.
- *
- * The bundler processes each entry point into a single file, each with no external dependencies and
- * minified. This primarily involves resolving all imports, along with some other transformations
- * (like TypeScript compilation).
- *
- * See the bundlers documentation for more information:
- * https://esbuild.github.io/getting-started/#bundling-for-node. */
-import * as fs from 'node:fs/promises'
-import * as path from 'node:path'
-import * as url from 'node:url'
-
-import * as esbuildPluginNodeModules from '@esbuild-plugins/node-modules-polyfill'
-import type * as esbuild from 'esbuild'
-import esbuildPluginInlineImage from 'esbuild-plugin-inline-image'
-import esbuildPluginTime from 'esbuild-plugin-time'
-import esbuildPluginYaml from 'esbuild-plugin-yaml'
-import postcss from 'postcss'
-import tailwindcss from 'tailwindcss'
-import tailwindcssNesting from 'tailwindcss/nesting'
-
-import * as appConfig from 'enso-common/src/appConfig'
-import * as buildUtils from 'enso-common/src/buildUtils'
-
-import * as tailwindConfig from './tailwind.config'
-
-// =================
-// === Constants ===
-// =================
-
-const THIS_PATH = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)))
-
-// ====================
-// === Global setup ===
-// ====================
-
-await appConfig.readEnvironmentFromFile()
-
-// =============================
-// === Environment variables ===
-// =============================
-
-/** Mandatory build options. */
-export interface Arguments {
- /** Path where bundled files are output. */
- readonly outputPath: string
-}
-
-/** Get arguments from the environment. */
-export function argumentsFromEnv(): Arguments {
- const outputPath = path.resolve(buildUtils.requireEnv('ENSO_BUILD_GUI'), 'assets')
- return { outputPath }
-}
-
-// =======================
-// === Esbuild plugins ===
-// =======================
-
-/** A plugin to process all CSS files with Tailwind CSS. */
-export function esbuildPluginGenerateTailwind(): esbuild.Plugin {
- return {
- name: 'enso-generate-tailwind',
- setup: build => {
- const cssProcessor = postcss(
- tailwindcss({
- ...tailwindConfig.default,
- content: tailwindConfig.default.content.map(glob =>
- glob.replace(/^[.][/]/, THIS_PATH + '/')
- ),
- }),
- tailwindcssNesting()
- )
- build.onLoad({ filter: /tailwind\.css$/ }, async loadArgs => {
- const content = await fs.readFile(loadArgs.path, 'utf8')
- const result = await cssProcessor.process(content, {
- from: loadArgs.path,
- })
- return {
- contents: result.content,
- loader: 'css',
- watchFiles: [loadArgs.path],
- }
- })
- },
- }
-}
-
-// ================
-// === Bundling ===
-// ================
-
-/** Generate the bundler options. */
-export function bundlerOptions(args: Arguments) {
- const { outputPath } = args
- // This is required to prevent TypeScript from narrowing `true` to `boolean`.
- // eslint-disable-next-line no-restricted-syntax
- const trueBoolean = true as boolean
- const buildOptions = {
- absWorkingDir: THIS_PATH,
- bundle: trueBoolean,
- entryPoints: [path.resolve(THIS_PATH, 'src', 'tailwind.css')],
- outdir: outputPath,
- outbase: 'src',
- loader: {
- /* eslint-disable @typescript-eslint/naming-convention */
- // The `file` loader copies the file, and replaces the import with the path to the file.
- '.png': 'file',
- '.jpg': 'file',
- /* eslint-enable @typescript-eslint/naming-convention */
- },
- plugins: [
- // The CSS file needs to import a single SVG as a data URL.
- // For `bundle.ts` and `watch.ts`, `index.js` also includes various SVG icons
- // which need to be bundled.
- // Depending on file size, choose between `dataurl` and `file` loaders.
- // The `dataurl` loader replaces the import with the file, as a data URL. Using the
- // `file` loader, which copies the file and replaces the import with the path.
- /* eslint-disable @typescript-eslint/naming-convention */
- esbuildPluginInlineImage({ extensions: ['svg'] }),
- esbuildPluginNodeModules.NodeModulesPolyfillPlugin(),
- esbuildPluginTime(),
- // This is not strictly needed because the cloud frontend does not use
- // the Project Manager, however it is very difficult to conditionally exclude a module.
- esbuildPluginYaml.yamlPlugin({}),
- esbuildPluginGenerateTailwind(),
- ],
- alias: {
- '#': './src',
- },
- define: appConfig.getDefines(),
- pure: ['assert'],
- sourcemap: true,
- metafile: trueBoolean,
- format: 'esm',
- platform: 'browser',
- color: trueBoolean,
- } satisfies esbuild.BuildOptions
- // The narrower type is required to avoid non-null assertions elsewhere.
- // The intersection with `esbuild.BuildOptions` is required to allow adding extra properties.
- const correctlyTypedBuildOptions: esbuild.BuildOptions & typeof buildOptions = buildOptions
- return correctlyTypedBuildOptions
-}
-
-/** esbuild options for bundling (one-off build) the package.
- *
- * Relies on the environment variables to be set. */
-export function bundleOptions() {
- return bundlerOptions(argumentsFromEnv())
-}
diff --git a/app/ide-desktop/lib/project-manager-shim/package.json b/app/ide-desktop/lib/project-manager-shim/package.json
deleted file mode 100644
index 84461960c6d..00000000000
--- a/app/ide-desktop/lib/project-manager-shim/package.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "name": "enso-project-manager-shim",
- "version": "1.0.0",
- "type": "module",
- "exports": {
- ".": "./src/projectManagerShimMiddleware.ts",
- "./src/projectManagement": "./src/projectManagement.ts"
- },
- "dependencies": {
- "@types/tar": "^6.1.4",
- "enso-common": "workspace:*",
- "tar": "^6.2.0",
- "yaml": "^2.4.1"
- }
-}
diff --git a/app/ide-desktop/lib/project-manager-shim/src/desktopEnvironment.ts b/app/ide-desktop/lib/project-manager-shim/src/desktopEnvironment.ts
deleted file mode 100644
index 8590a9d87da..00000000000
--- a/app/ide-desktop/lib/project-manager-shim/src/desktopEnvironment.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file This module contains the logic for the detection of user-specific desktop environment attributes.
- */
-
-import * as childProcess from 'node:child_process'
-import * as os from 'node:os'
-import * as path from 'node:path'
-
-export const DOCUMENTS = getDocumentsPath()
-
-const CHILD_PROCESS_TIMEOUT = 3000
-
-/**
- * Detects path of the user documents directory depending on the operating system.
- */
-function getDocumentsPath(): string | undefined {
- if (process.platform === 'linux') {
- return getLinuxDocumentsPath()
- } else if (process.platform === 'darwin') {
- return getMacOsDocumentsPath()
- } else if (process.platform === 'win32') {
- return getWindowsDocumentsPath()
- } else {
- return
- }
-}
-
-/**
- * Returns the user documents path on Linux.
- */
-function getLinuxDocumentsPath(): string {
- const xdgDocumentsPath = getXdgDocumentsPath()
-
- return xdgDocumentsPath ?? path.join(os.homedir(), 'enso')
-}
-
-/**
- * Gets the documents directory from the XDG directory management system.
- */
-function getXdgDocumentsPath(): string | undefined {
- const out = childProcess.spawnSync('xdg-user-dir', ['DOCUMENTS'], {
- timeout: CHILD_PROCESS_TIMEOUT,
- })
-
- if (out.error !== undefined) {
- return
- } else {
- return out.stdout.toString().trim()
- }
-}
-
-/**
- * Get the user documents path. On macOS, `Documents` acts as a symlink pointing to the
- * real locale-specific user documents directory.
- */
-function getMacOsDocumentsPath(): string {
- return path.join(os.homedir(), 'Documents')
-}
-
-/**
- * Get the path to the `My Documents` Windows directory.
- */
-function getWindowsDocumentsPath(): string | undefined {
- const out = childProcess.spawnSync(
- 'reg',
- [
- 'query',
- 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders',
- '/v',
- 'personal',
- ],
- { timeout: CHILD_PROCESS_TIMEOUT }
- )
-
- if (out.error !== undefined) {
- return
- } else {
- const stdoutString = out.stdout.toString()
- return stdoutString.split(/\s\s+/)[4]
- }
-}
diff --git a/app/ide-desktop/lib/project-manager-shim/src/projectManagement.ts b/app/ide-desktop/lib/project-manager-shim/src/projectManagement.ts
deleted file mode 100644
index 660042c79da..00000000000
--- a/app/ide-desktop/lib/project-manager-shim/src/projectManagement.ts
+++ /dev/null
@@ -1,445 +0,0 @@
-/** @file This module contains functions for importing projects into the Project Manager.
- *
- * Eventually this module should be replaced with a new Project Manager API that supports
- * importing projects.
- * For now, we basically do the following:
- * - if the project is already in the Project Manager's location, we just open it;
- * - if the project is in a different location, we copy it to the Project Manager's location
- * and open it.
- * - if the project is a bundle, we extract it to the Project Manager's location and open it. */
-import * as crypto from 'node:crypto'
-import * as fs from 'node:fs'
-import * as os from 'node:os'
-import * as pathModule from 'node:path'
-import type * as stream from 'node:stream'
-
-import * as tar from 'tar'
-
-import * as common from 'enso-common'
-import * as buildUtils from 'enso-common/src/buildUtils'
-import * as desktopEnvironment from './desktopEnvironment'
-
-const logger = console
-
-// =================
-// === Constants ===
-// =================
-
-export const PACKAGE_METADATA_RELATIVE_PATH = 'package.yaml'
-export const PROJECT_METADATA_RELATIVE_PATH = '.enso/project.json'
-/** The filename suffix for the project bundle, including the leading period character. */
-const BUNDLED_PROJECT_SUFFIX = '.enso-project'
-
-// ======================
-// === Project Import ===
-// ======================
-
-/** Open a project from the given path. Path can be either a source file under the project root,
- * or the project bundle. If needed, the project will be imported into the Project Manager-enabled
- * location.
- * @returns Project ID (from Project Manager's metadata) identifying the imported project.
- * @throws {Error} if the path does not belong to a valid project. */
-export function importProjectFromPath(
- openedPath: string,
- directory?: string | null,
- name: string | null = null
-): string {
- directory ??= getProjectsDirectory()
- if (pathModule.extname(openedPath).endsWith(BUNDLED_PROJECT_SUFFIX)) {
- logger.log(`Path '${openedPath}' denotes a bundled project.`)
- // The second part of condition is for the case when someone names a directory
- // like `my-project.enso-project` and stores the project there.
- // Not the most fortunate move, but...
- if (isProjectRoot(openedPath)) {
- return importDirectory(openedPath, directory, name)
- } else {
- // Project bundle was provided, so we need to extract it first.
- return importBundle(openedPath, directory, name)
- }
- } else {
- logger.log(`Opening non-bundled file: '${openedPath}'.`)
- const rootPath = getProjectRoot(openedPath)
- // Check if the project root is under the projects directory. If it is, we can open it.
- // Otherwise, we need to install it first.
- if (rootPath == null) {
- const productName = common.PRODUCT_NAME
- const message = `File '${openedPath}' does not belong to the ${productName} project.`
- throw new Error(message)
- } else {
- return importDirectory(rootPath, directory, name)
- }
- }
-}
-
-/** Import the project from a bundle.
- * @returns Project ID (from Project Manager's metadata) identifying the imported project. */
-export function importBundle(
- bundlePath: string,
- directory?: string | null,
- name: string | null = null
-): string {
- directory ??= getProjectsDirectory()
- logger.log(
- `Importing project '${bundlePath}' from bundle${name != null ? ` as '${name}'` : ''}.`
- )
- // The bundle is a tarball, so we just need to extract it to the right location.
- const bundlePrefix = prefixInBundle(bundlePath)
- // We care about spurious '.' and '..' when stripping paths but not when generating name.
- const normalizedBundlePrefix =
- bundlePrefix != null
- ? pathModule.normalize(bundlePrefix).replace(/[\\/]+$/, '') // Also strip trailing slash.
- : null
- const dirNameBase =
- normalizedBundlePrefix != null &&
- normalizedBundlePrefix !== '.' &&
- normalizedBundlePrefix !== '..'
- ? normalizedBundlePrefix
- : bundlePath
- logger.log(`Bundle normalized prefix: '${String(normalizedBundlePrefix)}'.`)
- const targetPath = generateDirectoryName(dirNameBase, directory)
- logger.log(`Importing project as '${targetPath}'.`)
- fs.mkdirSync(targetPath, { recursive: true })
- // To be more resilient against different ways that user might attempt to create a bundle,
- // we try to support both archives that:
- // * contain a single directory with the project files - that directory name will be used
- // to generate a new target directory name;
- // * contain the project files directly - in this case, the archive filename will be used
- // to generate a new target directory name.
- // We try to tell apart these two cases by looking at the common prefix of the paths
- // of the files in the archive. If there is any, everything is under a single directory,
- // and we need to strip it.
- //
- // Additionally, we need to take into account that paths might be prefixed with `./` or not.
- // Thus, we need to adjust the number of path components to strip accordingly.
-
- logger.log(`Extracting bundle: '${bundlePath}' -> '${targetPath}'.`)
-
- // Strip trailing separator and split the path into pieces.
- const rootPieces = bundlePrefix != null ? bundlePrefix.split(/[\\/]/) : []
-
- // If the last element is empty string (i.e. we had trailing separator), drop it.
- if (rootPieces.length > 0 && rootPieces[rootPieces.length - 1] === '') {
- rootPieces.pop()
- }
-
- tar.extract({
- file: bundlePath,
- cwd: targetPath,
- sync: true,
- strip: rootPieces.length,
- })
- return bumpMetadata(targetPath, directory, name ?? null)
-}
-
-/** Upload the project from a bundle. */
-export async function uploadBundle(
- bundle: stream.Readable,
- directory?: string | null,
- name: string | null = null
-): Promise {
- directory ??= getProjectsDirectory()
- logger.log(`Uploading project from bundle${name != null ? ` as '${name}'` : ''}.`)
- const targetPath = generateDirectoryName(name ?? 'Project', directory)
- fs.mkdirSync(targetPath, { recursive: true })
- await new Promise(resolve => {
- bundle.pipe(tar.extract({ cwd: targetPath })).on('finish', resolve)
- })
- const entries = fs.readdirSync(targetPath)
- const firstEntry = entries[0]
- // If the directory only contains one subdirectory, replace the directory with its sole
- // subdirectory.
- if (entries.length === 1 && firstEntry != null) {
- if (fs.statSync(pathModule.join(targetPath, firstEntry)).isDirectory()) {
- const temporaryDirectoryName =
- targetPath + `_${crypto.randomUUID().split('-')[0] ?? ''}`
- fs.renameSync(targetPath, temporaryDirectoryName)
- fs.renameSync(pathModule.join(temporaryDirectoryName, firstEntry), targetPath)
- fs.rmdirSync(temporaryDirectoryName)
- }
- }
- return bumpMetadata(targetPath, directory, name ?? null)
-}
-
-/** Import the project so it becomes visible to the Project Manager.
- * @returns The project ID (from the Project Manager's metadata) identifying the imported project.
- * @throws {Error} if a race condition occurs when generating a unique project directory name. */
-export function importDirectory(
- rootPath: string,
- directory?: string | null,
- name: string | null = null
-): string {
- directory ??= getProjectsDirectory()
- if (isProjectInstalled(rootPath, directory)) {
- // Project is already visible to Project Manager, so we can just return its ID.
- logger.log(`Project already installed at '${rootPath}'.`)
- const id = getProjectId(rootPath)
- if (id != null) {
- return id
- } else {
- throw new Error(`Project already installed, but missing metadata.`)
- }
- } else {
- logger.log(
- `Importing a project copy from '${rootPath}'${name != null ? ` as '${name}'` : ''}.`
- )
- const targetPath = generateDirectoryName(rootPath, directory)
- if (fs.existsSync(targetPath)) {
- throw new Error(`Project directory '${targetPath}' already exists.`)
- } else {
- logger.log(`Copying: '${rootPath}' -> '${targetPath}'.`)
- fs.cpSync(rootPath, targetPath, { recursive: true })
- // Update the project ID, so we are certain that it is unique.
- // This would be violated, if we imported the same project multiple times.
- return bumpMetadata(targetPath, directory, name ?? null)
- }
- }
-}
-
-// ================
-// === Metadata ===
-// ================
-
-/** The Project Manager's metadata associated with a project. */
-interface ProjectMetadata {
- /** The ID of the project. It is only used in communication with project manager;
- * it has no semantic meaning. */
- readonly id: string
- /** The project variant. This is currently always `UserProject`. */
- readonly kind: 'UserProject'
- /** The date at which the project was created, in RFC3339 format. */
- readonly created: string
- /** The date at which the project was last opened, in RFC3339 format. */
- readonly lastOpened: string
-}
-
-/** A type guard function to check if an object conforms to the {@link ProjectMetadata} interface.
- *
- * This function checks if the input object has the required properties and correct types
- * to match the {@link ProjectMetadata} interface. It can be used at runtime to validate that
- * a given object has the expected shape.
- * @param value - The object to check against the ProjectMetadata interface.
- * @returns A boolean value indicating whether the object matches
- * the {@link ProjectMetadata} interface. */
-function isProjectMetadata(value: unknown): value is ProjectMetadata {
- return (
- typeof value === 'object' && value != null && 'id' in value && typeof value.id === 'string'
- )
-}
-
-/** Get the ID from the project metadata. */
-export function getProjectId(projectRoot: string): string | null {
- return getMetadata(projectRoot)?.id ?? null
-}
-
-/** Get the package name. */
-function getPackageName(projectRoot: string) {
- const path = pathModule.join(projectRoot, PACKAGE_METADATA_RELATIVE_PATH)
- const contents = fs.readFileSync(path, { encoding: 'utf-8' })
- const [, name] = contents.match(/^name: (.*)/) ?? []
- return name ?? null
-}
-
-/** Update the package name. */
-export function updatePackageName(projectRoot: string, name: string) {
- const path = pathModule.join(projectRoot, PACKAGE_METADATA_RELATIVE_PATH)
- const contents = fs.readFileSync(path, { encoding: 'utf-8' })
- const newContents = contents.replace(/^name: .*/, `name: ${name}`)
- fs.writeFileSync(path, newContents)
-}
-
-/** Create a project's metadata. */
-export function createMetadata(): ProjectMetadata {
- return {
- id: generateId(),
- kind: 'UserProject',
- created: new Date().toISOString(),
- lastOpened: new Date().toISOString(),
- }
-}
-
-/** Retrieve the project's metadata. */
-export function getMetadata(projectRoot: string): ProjectMetadata | null {
- const metadataPath = pathModule.join(projectRoot, PROJECT_METADATA_RELATIVE_PATH)
- try {
- const jsonText = fs.readFileSync(metadataPath, 'utf8')
- const metadata: unknown = JSON.parse(jsonText)
- return isProjectMetadata(metadata) ? metadata : null
- } catch {
- return null
- }
-}
-
-/** Write the project's metadata. */
-export function writeMetadata(projectRoot: string, metadata: ProjectMetadata): void {
- const metadataPath = pathModule.join(projectRoot, PROJECT_METADATA_RELATIVE_PATH)
- fs.mkdirSync(pathModule.dirname(metadataPath), { recursive: true })
- fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, buildUtils.INDENT_SIZE))
-}
-
-/** Update the project's metadata.
- * If the provided updater does not return anything, the metadata file is left intact.
- *
- * Returns the metadata returned from the updater function. */
-export function updateMetadata(
- projectRoot: string,
- updater: (initialMetadata: ProjectMetadata) => ProjectMetadata
-): ProjectMetadata {
- const metadata = getMetadata(projectRoot)
- const updatedMetadata = updater(metadata ?? createMetadata())
- writeMetadata(projectRoot, updatedMetadata)
- return updatedMetadata
-}
-
-// =========================
-// === Project Directory ===
-// =========================
-
-/** Check if the given path represents the root of an Enso project.
- * This is decided by the presence of the Project Manager's metadata. */
-export function isProjectRoot(candidatePath: string): boolean {
- const projectJsonPath = pathModule.join(candidatePath, PROJECT_METADATA_RELATIVE_PATH)
- try {
- fs.accessSync(projectJsonPath, fs.constants.R_OK)
- return true
- } catch {
- return false
- }
-}
-
-/** Check if this bundle is a compressed directory (rather than directly containing the project
- * files). If it is, we return the path to the directory. Otherwise, we return `null`. */
-export function prefixInBundle(bundlePath: string): string | null {
- // We need to look up the root directory among the tarball entries.
- let commonPrefix: string | null = null
- tar.list({
- file: bundlePath,
- sync: true,
- onentry: entry => {
- const path = entry.path
- commonPrefix =
- commonPrefix == null ? path : buildUtils.getCommonPrefix(commonPrefix, path)
- },
- })
-
- // ESLint doesn't know that `commonPrefix` can be not `null` here due to the `onentry` callback.
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
- return commonPrefix != null && commonPrefix !== '' ? commonPrefix : null
-}
-
-/** Generate a name for a project using given base string. A suffix is added if there is a
- * collision.
- *
- * For example `Name` will become `Name_1` if there's already a directory named `Name`.
- * If given a name like `Name_1` it will become `Name_2` if there is already a directory named
- * `Name_1`. If a path containing multiple components is given, only the last component is used
- * for the name. */
-export function generateDirectoryName(name: string, directory = getProjectsDirectory()): string {
- // Use only the last path component.
- name = pathModule.parse(name).name
-
- // If the name already consists a suffix, reuse it.
- const matches = name.match(/^(.*)_(\d+)$/)
- const initialSuffix = -1
- let suffix = initialSuffix
- // Matches start with the whole match, so we need to skip it. Then come our two capture groups.
- const [matchedName, matchedSuffix] = matches?.slice(1) ?? []
- if (typeof matchedName !== 'undefined' && typeof matchedSuffix !== 'undefined') {
- name = matchedName
- suffix = parseInt(matchedSuffix)
- }
-
- let finalPath: string
- while (true) {
- suffix++
- const newName = `${name}${suffix === 0 ? '' : `_${suffix}`}`
- const candidatePath = pathModule.join(directory, newName)
- if (!fs.existsSync(candidatePath)) {
- finalPath = candidatePath
- break
- }
- }
- return finalPath
-}
-
-/** Take a path to a file, presumably located in a project's subtree.Returns the path
- * to the project's root directory or `null` if the file is not located in a project. */
-export function getProjectRoot(subtreePath: string): string | null {
- let currentPath = subtreePath
- while (!isProjectRoot(currentPath)) {
- const parent = pathModule.dirname(currentPath)
- if (parent === currentPath) {
- // eslint-disable-next-line no-restricted-syntax
- return null
- }
- currentPath = parent
- }
- return currentPath
-}
-
-/** Get the directory that stores Enso projects. */
-export function getProjectsDirectory(): string {
- const documentsPath = desktopEnvironment.DOCUMENTS
- if (documentsPath === undefined) {
- return pathModule.join(os.homedir(), 'enso', 'projects')
- } else {
- return pathModule.join(documentsPath, 'enso-projects')
- }
-}
-
-/** Check if the given project is installed, i.e. can be opened with the Project Manager. */
-export function isProjectInstalled(
- projectRoot: string,
- directory = getProjectsDirectory()
-): boolean {
- const projectRootParent = pathModule.dirname(projectRoot)
- // Should resolve symlinks and relative paths. Normalize before comparison.
- return pathModule.resolve(projectRootParent) === pathModule.resolve(directory)
-}
-
-// ==================
-// === Project ID ===
-// ==================
-
-/** Generate a unique UUID for a project. */
-export function generateId(): string {
- return crypto.randomUUID()
-}
-
-/** Update the project's ID to a new, unique value, and its last opened date to the current date. */
-export function bumpMetadata(
- projectRoot: string,
- parentDirectory: string,
- name: string | null
-): string {
- if (name == null) {
- const currentName = getPackageName(projectRoot) ?? ''
- let index: number | null = null
- const prefix = `${currentName} `
- for (const sibling of fs.readdirSync(parentDirectory, { withFileTypes: true })) {
- if (sibling.isDirectory()) {
- try {
- const siblingPath = pathModule.join(parentDirectory, sibling.name)
- const siblingName = getPackageName(siblingPath)
- if (siblingName === currentName) {
- index = index ?? 2
- } else if (siblingName != null && siblingName.startsWith(prefix)) {
- const suffix = siblingName.replace(prefix, '')
- const [, numberString] = suffix.match(/^\((\d+)\)/) ?? []
- if (numberString != null) {
- index = Math.max(index ?? 2, Number(numberString) + 1)
- }
- }
- } catch {
- // Ignored - it is a directory but not a project.
- }
- }
- }
- name = index == null ? currentName : `${currentName} (${index})`
- }
- updatePackageName(projectRoot, name)
- return updateMetadata(projectRoot, metadata => ({
- ...metadata,
- id: generateId(),
- lastOpened: new Date().toISOString(),
- })).id
-}
diff --git a/app/ide-desktop/lib/project-manager-shim/src/projectManagerShimMiddleware.ts b/app/ide-desktop/lib/project-manager-shim/src/projectManagerShimMiddleware.ts
deleted file mode 100644
index de0ffae08aa..00000000000
--- a/app/ide-desktop/lib/project-manager-shim/src/projectManagerShimMiddleware.ts
+++ /dev/null
@@ -1,485 +0,0 @@
-/** @file A simple HTTP server which serves application data to the Electron web-view. */
-
-import * as fs from 'node:fs/promises'
-import * as fsSync from 'node:fs'
-import * as http from 'node:http'
-import * as path from 'node:path'
-
-import * as tar from 'tar'
-import * as yaml from 'yaml'
-
-import * as common from 'enso-common'
-import GLOBAL_CONFIG from '../../common/src/config.json' assert { type: 'json' }
-
-import * as projectManagement from './projectManagement'
-
-// =================
-// === Constants ===
-// =================
-
-const HTTP_STATUS_OK = 200
-const HTTP_STATUS_BAD_REQUEST = 400
-const HTTP_STATUS_NOT_FOUND = 404
-const PROJECTS_ROOT_DIRECTORY = projectManagement.getProjectsDirectory()
-
-// =============
-// === Types ===
-// =============
-
-/** Details of a project. */
-interface ProjectMetadata {
- /** The name of the project. */
- readonly name: string
- /** The namespace of the project. */
- readonly namespace: string
- /** The project id. */
- readonly id: string
- /** The Enso Engine version to use for the project, represented by a semver version
- * string.
- *
- * If the edition associated with the project could not be resolved, the
- * engine version may be missing. */
- readonly engineVersion?: string
- /** The project creation time. */
- readonly created: string
- /** The last opened datetime. */
- readonly lastOpened?: string
-}
-
-/** Attributes of a file or folder. */
-interface Attributes {
- readonly creationTime: string
- readonly lastAccessTime: string
- readonly lastModifiedTime: string
- readonly byteSize: number
-}
-
-/** Metadata for an arbitrary file system entry. */
-type FileSystemEntry = DirectoryEntry | FileEntry | ProjectEntry
-
-/** The discriminator value for {@link FileSystemEntry}. */
-export enum FileSystemEntryType {
- DirectoryEntry = 'DirectoryEntry',
- ProjectEntry = 'ProjectEntry',
- FileEntry = 'FileEntry',
-}
-
-/** Metadata for a file. */
-interface FileEntry {
- readonly type: FileSystemEntryType.FileEntry
- readonly path: string
- readonly attributes: Attributes
-}
-
-/** Metadata for a directory. */
-interface DirectoryEntry {
- readonly type: FileSystemEntryType.DirectoryEntry
- readonly path: string
- readonly attributes: Attributes
-}
-
-/** Metadata for a project. */
-interface ProjectEntry {
- readonly type: FileSystemEntryType.ProjectEntry
- readonly path: string
- readonly metadata: ProjectMetadata
- readonly attributes: Attributes
-}
-
-// ====================================
-// === projectManagerShimMiddleware ===
-// ====================================
-
-/** A middleware that handles */
-export default function projectManagerShimMiddleware(
- request: http.IncomingMessage,
- response: http.ServerResponse,
- next: () => void
-) {
- const requestUrl = request.url
- const requestPath = requestUrl?.split('?')[0]?.split('#')[0]
- if (requestUrl != null && requestUrl.startsWith('/api/project-manager/')) {
- const actualUrl = new URL(
- requestUrl.replace(/^\/api\/project-manager/, GLOBAL_CONFIG.projectManagerHttpEndpoint)
- )
- request.pipe(
- http.request(
- // `...actualUrl` does NOT work because `URL` properties are not enumerable.
- {
- headers: request.headers,
- host: actualUrl.host,
- hostname: actualUrl.hostname,
- method: request.method,
- path: actualUrl.pathname,
- port: actualUrl.port,
- protocol: actualUrl.protocol,
- },
- actualResponse => {
- response.writeHead(
- // This is SAFE. The documentation says:
- // Only valid for response obtained from ClientRequest.
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- actualResponse.statusCode!,
- actualResponse.statusMessage,
- actualResponse.headers
- )
- actualResponse.pipe(response, { end: true })
- }
- ),
- { end: true }
- )
- } else if (request.method === 'POST') {
- switch (requestPath) {
- case '/api/upload-file': {
- const url = new URL(`https://example.com/${requestUrl}`)
- const fileName = url.searchParams.get('file_name')
- const directory = url.searchParams.get('directory') ?? PROJECTS_ROOT_DIRECTORY
- if (fileName == null) {
- response
- .writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS)
- .end('Request is missing search parameter `file_name`.')
- } else {
- const filePath = path.join(directory, fileName)
- void fs
- .writeFile(filePath, request)
- .then(() => {
- response
- .writeHead(HTTP_STATUS_OK, [
- ['Content-Length', String(filePath.length)],
- ['Content-Type', 'text/plain'],
- ...common.COOP_COEP_CORP_HEADERS,
- ])
- .end(filePath)
- })
- .catch(e => {
- console.error(e)
- response
- .writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS)
- .end()
- })
- }
- break
- }
- // This endpoint should only be used when accessing the app from the browser.
- // When accessing the app from Electron, the file input event will have the
- // full system path.
- case '/api/upload-project': {
- const url = new URL(`https://example.com/${requestUrl}`)
- const directory = url.searchParams.get('directory')
- const name = url.searchParams.get('name')
- void projectManagement
- .uploadBundle(request, directory, name)
- .then(id => {
- response
- .writeHead(HTTP_STATUS_OK, [
- ['Content-Length', String(id.length)],
- ['Content-Type', 'text/plain'],
- ...common.COOP_COEP_CORP_HEADERS,
- ])
- .end(id)
- })
- .catch(() => {
- response
- .writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS)
- .end()
- })
- break
- }
- case '/api/run-project-manager-command': {
- const cliArguments: unknown = JSON.parse(
- new URL(`https://example.com/${requestUrl}`).searchParams.get(
- 'cli-arguments'
- ) ?? '[]'
- )
- if (
- !Array.isArray(cliArguments) ||
- !cliArguments.every((item): item is string => typeof item === 'string')
- ) {
- response
- .writeHead(HTTP_STATUS_BAD_REQUEST, common.COOP_COEP_CORP_HEADERS)
- .end('Command arguments must be an array of strings.')
- } else {
- void (async () => {
- const toJSONRPCResult = (result: unknown) =>
- JSON.stringify({ jsonrpc: '2.0', id: 0, result })
- const toJSONRPCError = (message: string, data?: unknown) =>
- JSON.stringify({
- jsonrpc: '2.0',
- id: 0,
- error: { code: 0, message, ...(data != null ? { data } : {}) },
- })
- let result = toJSONRPCError(`Error running Project Manager command.`, {
- command: cliArguments,
- })
- try {
- switch (cliArguments[0]) {
- case '--filesystem-exists': {
- const directoryPath = cliArguments[1]
- if (directoryPath != null) {
- const exists = await fs
- .access(directoryPath)
- .then(() => true)
- .catch(() => false)
- result = toJSONRPCResult({ exists })
- }
- break
- }
- case '--filesystem-list': {
- const directoryPath = cliArguments[1]
- if (directoryPath != null) {
- const entryNames = await fs.readdir(directoryPath)
- const entries: FileSystemEntry[] = []
- for (const entryName of entryNames) {
- const entryPath = path.join(directoryPath, entryName)
- if (isHidden(entryPath)) continue
- const stat = await fs.stat(entryPath)
- const attributes: Attributes = {
- byteSize: stat.size,
- creationTime: new Date(stat.ctimeMs).toISOString(),
- lastAccessTime: new Date(
- stat.atimeMs
- ).toISOString(),
- lastModifiedTime: new Date(
- stat.mtimeMs
- ).toISOString(),
- }
- if (stat.isFile()) {
- entries.push({
- type: FileSystemEntryType.FileEntry,
- path: entryPath,
- attributes,
- } satisfies FileEntry)
- } else {
- try {
- const packageMetadataPath = path.join(
- entryPath,
- 'package.yaml'
- )
- const projectMetadataPath = path.join(
- entryPath,
- projectManagement.PROJECT_METADATA_RELATIVE_PATH
- )
- const packageMetadataContents =
- await fs.readFile(packageMetadataPath)
- const projectMetadataContents =
- await fs.readFile(projectMetadataPath)
- const metadata = extractProjectMetadata(
- yaml.parse(
- packageMetadataContents.toString()
- ),
- JSON.parse(
- projectMetadataContents.toString()
- )
- )
- if (metadata != null) {
- // This is a project.
- entries.push({
- type: FileSystemEntryType.ProjectEntry,
- path: entryPath,
- attributes,
- metadata,
- } satisfies ProjectEntry)
- } else {
- // This error moves control flow to the
- // `catch` clause directly below.
- // eslint-disable-next-line no-restricted-syntax
- throw new Error('Invalid project metadata.')
- }
- } catch {
- // This is a regular directory, not a project.
- entries.push({
- type: FileSystemEntryType.DirectoryEntry,
- path: entryPath,
- attributes,
- } satisfies DirectoryEntry)
- }
- }
- }
- result = toJSONRPCResult({ entries })
- }
- break
- }
- case '--filesystem-create-directory': {
- const directoryPath = cliArguments[1]
- if (directoryPath != null) {
- await fs.mkdir(directoryPath, { recursive: true })
- result = toJSONRPCResult(null)
- }
- break
- }
- case '--filesystem-write-path': {
- const filePath = cliArguments[1]
- if (filePath != null) {
- await new Promise((resolve, reject) => {
- request
- .pipe(fsSync.createWriteStream(filePath), {
- end: true,
- })
- .on('close', resolve)
- .on('error', reject)
- })
- result = toJSONRPCResult(null)
- }
- break
- }
- case '--filesystem-move-from': {
- const sourcePath = cliArguments[1]
- const destinationPath = cliArguments[3]
- if (
- sourcePath != null &&
- cliArguments[2] === '--filesystem-move-to' &&
- destinationPath != null
- ) {
- await fs.rename(sourcePath, destinationPath)
- result = toJSONRPCResult(null)
- }
- break
- }
- case '--filesystem-delete': {
- const fileOrDirectoryPath = cliArguments[1]
- if (fileOrDirectoryPath != null) {
- await fs.rm(fileOrDirectoryPath, { recursive: true })
- result = toJSONRPCResult(null)
- }
- break
- }
- default: {
- // Ignored. `result` retains its original value indicating an error.
- }
- }
- } catch {
- // Ignored. `result` retains its original value indicating an error.
- }
- const buffer = Buffer.from(result)
- response
- .writeHead(HTTP_STATUS_OK, [
- ['Content-Length', String(buffer.byteLength)],
- ['Content-Type', 'application/json'],
- ...common.COOP_COEP_CORP_HEADERS,
- ])
- .end(buffer)
- })()
- }
- break
- }
- default: {
- const downloadProjectMatch = requestPath?.match(
- /^[/]api[/]project-manager[/]projects[/]([^/]+)[/]enso-project$/
- )
- if (downloadProjectMatch) {
- const uuid = downloadProjectMatch[1]
- void fs.readdir(PROJECTS_ROOT_DIRECTORY).then(async filenames => {
- let success = false
- for (const filename of filenames) {
- try {
- const projectRoot = path.join(PROJECTS_ROOT_DIRECTORY, filename)
- const stat = await fs.stat(projectRoot)
- if (stat.isDirectory()) {
- const metadataPath = path.join(
- projectRoot,
- projectManagement.PROJECT_METADATA_RELATIVE_PATH
- )
- const metadataContents = await fs.readFile(metadataPath)
- const metadata: unknown = JSON.parse(
- metadataContents.toString()
- )
- if (
- typeof metadata === 'object' &&
- metadata != null &&
- 'id' in metadata &&
- metadata.id === uuid
- ) {
- response.writeHead(HTTP_STATUS_OK, [
- ['Content-Type', 'application/gzip+x-enso-project'],
- ...common.COOP_COEP_CORP_HEADERS,
- ])
- tar.create({ gzip: true, cwd: projectRoot }, [
- projectRoot,
- ]).pipe(response, { end: true })
- success = true
- break
- }
- }
- } catch {
- // Ignored.
- }
- }
- if (!success) {
- response
- .writeHead(HTTP_STATUS_NOT_FOUND, common.COOP_COEP_CORP_HEADERS)
- .end()
- }
- })
- break
- }
- response.writeHead(HTTP_STATUS_NOT_FOUND, common.COOP_COEP_CORP_HEADERS).end()
- break
- }
- }
- } else if (request.method === 'GET' && requestPath === '/api/root-directory') {
- response
- .writeHead(HTTP_STATUS_OK, [
- ['Content-Length', String(PROJECTS_ROOT_DIRECTORY.length)],
- ['Content-Type', 'text/plain'],
- ...common.COOP_COEP_CORP_HEADERS,
- ])
- .end(PROJECTS_ROOT_DIRECTORY)
- } else {
- next()
- }
-}
-
-/** Return a {@link ProjectMetadata} if the metadata is a valid metadata object,
- * else return `null`. */
-function extractProjectMetadata(yamlObj: unknown, jsonObj: unknown): ProjectMetadata | null {
- if (
- typeof yamlObj !== 'object' ||
- yamlObj == null ||
- typeof jsonObj !== 'object' ||
- jsonObj == null
- ) {
- return null
- } else {
- const validDateString = (string: string) => {
- const date = new Date(string)
- return !Number.isNaN(Number(date)) ? date.toString() : null
- }
- const name = 'name' in yamlObj && typeof yamlObj.name === 'string' ? yamlObj.name : null
- const namespace =
- 'namespace' in yamlObj && typeof yamlObj.namespace === 'string'
- ? yamlObj.namespace
- : null
- const engineVersion =
- 'edition' in yamlObj && typeof yamlObj.edition === 'string' ? yamlObj.edition : null
- const id = 'id' in jsonObj && typeof jsonObj.id === 'string' ? jsonObj.id : null
- const created =
- 'created' in jsonObj && typeof jsonObj.created === 'string'
- ? validDateString(jsonObj.created)
- : null
- const lastOpened =
- 'lastOpened' in jsonObj && typeof jsonObj.lastOpened === 'string'
- ? validDateString(jsonObj.lastOpened)
- : null
- if (name != null && namespace != null && id != null && created != null) {
- return {
- name,
- namespace,
- id,
- ...(engineVersion != null ? { engineVersion } : {}),
- created,
- ...(lastOpened != null ? { lastOpened } : {}),
- } satisfies ProjectMetadata
- } else {
- return null
- }
- }
-}
-
-/**
- * Checks if files that start with the dot.
- * Note on Windows does not check the hidden property.
- */
-function isHidden(filePath: string): boolean {
- const dotfile = /(^|[\\/])\.[^\\/]+$/g
- return dotfile.test(filePath)
-}
diff --git a/app/ide-desktop/lib/project-manager-shim/tsconfig.json b/app/ide-desktop/lib/project-manager-shim/tsconfig.json
deleted file mode 100644
index c2dcc3ed7b1..00000000000
--- a/app/ide-desktop/lib/project-manager-shim/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "allowJs": false,
- "checkJs": false,
- "skipLibCheck": false
- },
- "include": ["./src/", "../common/src/config.json"]
-}
diff --git a/app/ide-desktop/lib/ts-plugin-namespace-auto-import/index.js b/app/ide-desktop/lib/ts-plugin-namespace-auto-import/index.js
deleted file mode 100644
index 96e10ad1d7f..00000000000
--- a/app/ide-desktop/lib/ts-plugin-namespace-auto-import/index.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/** @file A plugin to change auto-imports to use `import * as module` instead of `import {}`. */
-
-/** A TypeScript compiler plugin. */
-module.exports = function init() {
- /** Turn a module name into a valid identifier.
- * @param {string} name - module name */
- const normalizeModuleName = name => {
- const intermediate = name.length === 0 ? '' : name[0].toLowerCase() + name.slice(1)
- const result = intermediate.replace(/^\W+|\W+(.?)/g, (_, a) =>
- String(a ?? '').toUpperCase()
- )
- return NON_CONTEXTUAL_KEYWORDS.has(result) ? '_' + result : result
- }
-
- /** Create the plugin.
- * @param {import('typescript/lib/tsserverlibrary').server.PluginCreateInfo} info - Plugin utilities. */
- const create = info => {
- /** @type {import('typescript/lib/tsserverlibrary').LanguageService} */
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- const proxy = Object.create(null)
- const oldLS = info.languageService
- for (const [k, v] of Object.entries(oldLS)) {
- // @ts-expect-error Runtime reflection is not type-safe.
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
- proxy[k] = (...args) => v.apply(oldLS, args)
- }
-
- proxy.getCompletionsAtPosition = (fileName, position, options) => {
- const result = info.languageService.getCompletionsAtPosition(
- fileName,
- position,
- options
- )
- for (const completion of result?.entries ?? []) {
- if (
- completion.hasAction &&
- /\bexport\b/.test(completion.kindModifiers ?? '') &&
- completion.data?.exportName !== 'default'
- ) {
- const moduleName = completion.data?.moduleSpecifier?.match(/[^/]+$/)?.[0] ?? ''
- if (moduleName) {
- completion.insertText = `${normalizeModuleName(moduleName)}.${
- completion.name
- }`
- }
- }
- }
- return result
- }
-
- proxy.getCompletionEntryDetails = (
- fileName,
- position,
- entryName,
- formatOptions,
- source,
- preferences,
- data
- ) => {
- const result = info.languageService.getCompletionEntryDetails(
- fileName,
- position,
- entryName,
- formatOptions,
- source,
- preferences,
- data
- )
- for (const action of result?.codeActions ?? []) {
- if (action.description.startsWith('Add import from ')) {
- for (const change of action.changes) {
- for (const textChange of change.textChanges) {
- textChange.newText = textChange.newText.replace(
- /^(import ){.*}( from (['"])(?:.*[/])?(.*)\3)/m,
- (_, prefix, suffix, _quote, moduleName) =>
- `${prefix}* as ${normalizeModuleName(
- String(moduleName)
- )}${suffix}`
- )
- }
- }
- } else if (action.description.startsWith('Update import from ')) {
- const moduleName =
- action.description.match(/(['"])(?:.*[/])?(?.*)\1/)?.groups
- ?.moduleName ?? ''
- const replacement = `, * as ${normalizeModuleName(moduleName)}`
- for (const change of action.changes) {
- for (const textChange of change.textChanges) {
- textChange.newText = textChange.newText.replace(
- /^, {.*}$/m,
- replacement
- )
- }
- }
- // "Change 'foo' to 'module.foo'"
- } else if (/^Change '(.*)' to '.*[.]\1'$/.test(action.description)) {
- for (const change of action.changes) {
- for (const textChange of change.textChanges) {
- textChange.newText = ''
- }
- }
- }
- }
- return result
- }
-
- return proxy
- }
-
- return { create }
-}
-
-const NON_CONTEXTUAL_KEYWORDS = new Set([
- 'break',
- 'case',
- 'catch',
- 'class',
- 'const',
- 'continue',
- 'debugger',
- 'default',
- 'delete',
- 'do',
- 'else',
- 'enum',
- 'export',
- 'extends',
- 'false',
- 'finally',
- 'for',
- 'function',
- 'if',
- 'import',
- 'in',
- 'instanceof',
- 'new',
- 'null',
- 'return',
- 'super',
- 'switch',
- 'this',
- 'throw',
- 'true',
- 'try',
- 'typeof',
- 'var',
- 'void',
- 'while',
- 'with',
- 'implements',
- 'interface',
- 'let',
- 'package',
- 'private',
- 'protected',
- 'public',
- 'static',
- 'yield',
-])
diff --git a/app/ide-desktop/lib/ts-plugin-namespace-auto-import/package.json b/app/ide-desktop/lib/ts-plugin-namespace-auto-import/package.json
deleted file mode 100644
index 3e2fe593d72..00000000000
--- a/app/ide-desktop/lib/ts-plugin-namespace-auto-import/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "ts-plugin-namespace-auto-import",
- "version": "1.0.0",
- "type": "commonjs",
- "author": {
- "name": "Enso Team",
- "email": "contact@enso.org"
- },
- "homepage": "https://github.com/enso-org/enso",
- "repository": {
- "type": "git",
- "url": "git@github.com:enso-org/enso.git"
- },
- "bugs": {
- "url": "https://github.com/enso-org/enso/issues"
- },
- "devDependencies": {
- "typescript": "^5.5.3"
- }
-}
diff --git a/app/ide-desktop/lib/ts-plugin-namespace-auto-import/tsconfig.json b/app/ide-desktop/lib/ts-plugin-namespace-auto-import/tsconfig.json
deleted file mode 100644
index dd0a304932b..00000000000
--- a/app/ide-desktop/lib/ts-plugin-namespace-auto-import/tsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "compilerOptions": {
- "module": "CommonJS",
- "noEmit": true,
- "allowJs": true,
- "checkJs": true,
- "strict": true
- }
-}
diff --git a/app/ide-desktop/lib/types/ipc.d.ts b/app/ide-desktop/lib/types/ipc.d.ts
deleted file mode 100644
index 4300ae2169d..00000000000
--- a/app/ide-desktop/lib/types/ipc.d.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * @file This file contains the types for the IPC events.
- * The IPC events are used to communicate between the main and renderer processes.
- */
-/**
- * Payload for the save-access-token event that saves an access token to a credentials file.
- */
-interface SaveAccessTokenPayload {
- /**
- * The JWT token to save.
- */
- readonly accessToken: string
- /**
- * The Cognito app integration client id
- */
- readonly clientId: string
- /**
- * The refresh token taken from initAuth flow.
- */
- readonly refreshToken: string
- /**
- * The Cognito url to refresh the token.
- */
- readonly refreshUrl: string
- /**
- * Time when the token will expire.
- * This is a string representation of a date in ISO 8601 format (e.g. "2021-01-01T00:00:00Z").
- */
- readonly expireAt: string
-}
diff --git a/app/ide-desktop/lib/types/tsconfig.json b/app/ide-desktop/lib/types/tsconfig.json
deleted file mode 100644
index 1ff66ebeea0..00000000000
--- a/app/ide-desktop/lib/types/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "include": ["./*"],
- "compilerOptions": {
- "types": ["node"],
- "lib": ["ES2015", "DOM"],
- "skipLibCheck": false,
- "outDir": "../../../../node_modules/.cache/tsc"
- },
- "extends": "../../tsconfig.json"
-}
diff --git a/app/ide-desktop/package.json b/app/ide-desktop/package.json
deleted file mode 100644
index 314a3697665..00000000000
--- a/app/ide-desktop/package.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
- "name": "enso-ide-desktop",
- "version": "1.0.0",
- "type": "module",
- "author": {
- "name": "Enso Team",
- "email": "contact@enso.org"
- },
- "homepage": "https://github.com/enso-org/enso",
- "repository": {
- "type": "git",
- "url": "git@github.com:enso-org/enso.git"
- },
- "bugs": {
- "url": "https://github.com/enso-org/enso/issues"
- },
- "private": true,
- "devDependencies": {
- "@types/node": "^20.11.21",
- "@types/react": "^18.0.27",
- "@typescript-eslint/eslint-plugin": "^7.15.0",
- "@typescript-eslint/parser": "^7.15.0",
- "cross-env": "^7.0.3",
- "esbuild": "^0.19.3",
- "eslint": "^8.49.0",
- "eslint-plugin-jsdoc": "^46.8.1",
- "eslint-plugin-react": "^7.32.2",
- "eslint-plugin-react-hooks": "^4.6.0",
- "fast-check": "^3.15.0",
- "globals": "^14.0.0",
- "typescript": "^5.5.3",
- "vite": "^5.3.3"
- },
- "scripts": {
- "dev": "npm run watch --workspace enso-content",
- "typecheck": "tsc -p lib/types/tsconfig.json",
- "lint-only": "eslint .",
- "lint": "npm run --workspace=enso-gui2 compile-server && npm run lint-only"
- },
- "dependencies": {
- "@stripe/react-stripe-js": "^2.3.1",
- "@stripe/stripe-js": "^2.1.10",
- "esbuild-plugin-inline-image": "^0.0.9",
- "eslint-plugin-react": "^7.32.2",
- "eslint-plugin-react-hooks": "^4.6.0"
- }
-}
diff --git a/app/ide-desktop/lib/types/modules.d.ts b/app/modules.d.ts
similarity index 50%
rename from app/ide-desktop/lib/types/modules.d.ts
rename to app/modules.d.ts
index 0bde27c06ee..335fc88f365 100644
--- a/app/ide-desktop/lib/types/modules.d.ts
+++ b/app/modules.d.ts
@@ -1,51 +1,11 @@
-/** @file Type definitions for modules that currently don't have typings on DefinitelyTyped.
+/** @file Type definitions for modules that currently lack typings on DefinitelyTyped.
*
- * This file MUST NOT `export {}` for the modules to be visible to other files. */
+ * This file MUST NOT `export {}` so that the modules are visible to other files. */
// ===========================
// === Module declarations ===
// ===========================
-// Required because this is a build artifact, which does not exist on a clean repository.
-declare module '*/build.json' {
- /** Build metadata generated by the build CLI. */
- export interface BuildInfo {
- readonly commit: string
- readonly version: string
- readonly engineVersion: string
- readonly name: string
- }
-
- const BUILD_INFO: BuildInfo
- export default BUILD_INFO
-}
-
-declare module '@eslint/js' {
- /** A set of configurations. */
- export interface Config {
- readonly rules: Record
- }
-
- /** Preset configurations defined by ESLint. */
- export interface EslintConfigs {
- readonly all: Config
- readonly recommended: Config
- }
-
- /** The default export of the module. */
- export interface Default {
- readonly configs: EslintConfigs
- }
-
- const DEFAULT: Default
- export default DEFAULT
-}
-
-declare module 'eslint-plugin-jsdoc' {
- const DEFAULT: unknown
- export default DEFAULT
-}
-
declare module 'eslint-plugin-react' {
/** An ESLint configuration. */
interface Config {
@@ -122,49 +82,3 @@ declare module 'eslint-plugin-react-hooks' {
const DEFAULT: Default
export default DEFAULT
}
-
-declare module 'esbuild-plugin-time' {
- import type * as esbuild from 'esbuild'
-
- export default function (name?: string): esbuild.Plugin
-}
-
-declare module 'create-servers' {
- import type * as http from 'node:http'
- import type * as https from 'node:https'
-
- /** Configuration options for `create-servers`. */
- interface CreateServersOptions {
- readonly http?: number
- readonly handler: http.RequestListener
- // eslint-disable-next-line no-restricted-syntax
- readonly https?: {
- readonly port: number
- readonly key: string
- readonly cert: string
- }
- }
-
- /** An error passed to a callback when a HTTP request fails. */
- interface HttpError {
- readonly http: string
- }
-
- /** Created server instances of various types. */
- interface CreatedServers {
- readonly http?: http.Server
- readonly https?: https.Server
- }
-
- export default function (
- option: CreateServersOptions,
- // The types come from a third-party API and cannot be changed.
- // eslint-disable-next-line no-restricted-syntax
- handler: (err: HttpError | undefined, servers: CreatedServers) => void
- ): unknown
-}
-
-declare module 'wasm_rust_glue' {
- const DEFAULT: unknown
- export default DEFAULT
-}
diff --git a/app/ide-desktop/tsconfig.json b/app/tsconfig.json
similarity index 100%
rename from app/ide-desktop/tsconfig.json
rename to app/tsconfig.json
diff --git a/build/build/paths.yaml b/build/build/paths.yaml
index b6ff88b881e..c93407f321c 100644
--- a/build/build/paths.yaml
+++ b/build/build/paths.yaml
@@ -17,7 +17,6 @@
shader-tools.yml:
std-libs-benchmark.yml:
app/:
- gui/:
gui2/: # The new, Vue-based GUI.
dist/:
playwright-report/: # Test results for the new GUI that we want to keep as artifacts.
@@ -30,17 +29,12 @@
font-enso.css:
font-mplus1.css:
font-dejavu.css:
+ dashboard/:
+ playwright-report/: # Test results for the dashboard that we want to keep as artifacts.
ide-desktop/:
- lib/:
- client/:
- content/:
- content-config/:
- src/:
- config.json:
- dashboard/:
- playwright-report/: # Test results for the dashboard that we want to keep as artifacts.
- icons/:
- project-manager/:
+ client/:
+ common/:
+ icons/:
build/:
prettier/:
built-distribution/:
diff --git a/build/build/src/ide/web.rs b/build/build/src/ide/web.rs
index 97c219c96b5..f1fd041e4ad 100644
--- a/build/build/src/ide/web.rs
+++ b/build/build/src/ide/web.rs
@@ -123,7 +123,7 @@ pub fn unpacked_dir(output_path: impl AsRef, os: OS, arch: Arch) -> PathBu
/// Computes the SHA-256 checksum of a file and writes it to a file.
///
-/// This is a Rust equivalent of the `app/ide-desktop/lib/client/tasks/computeHashes.mjs`.
+/// This is a Rust equivalent of the `app/ide-desktop/client/tasks/computeHashes.mjs`.
pub fn store_sha256_checksum(file: impl AsRef, checksum_file: impl AsRef) -> Result {
let mut hasher = sha2::Sha256::new();
let mut file = ide_ci::fs::open(&file)?;
diff --git a/build/cli/src/lib.rs b/build/cli/src/lib.rs
index b627485e3f3..c5f206394a6 100644
--- a/build/cli/src/lib.rs
+++ b/build/cli/src/lib.rs
@@ -348,7 +348,7 @@ impl Processor {
);
let dashboard_tests = run_and_upload_dir(
gui::dashboard_tests(&repo_root),
- &repo_root.app.ide_desktop.lib.dashboard.playwright_report,
+ &repo_root.app.dashboard.playwright_report,
"dashboard-playwright-report",
);
try_join(gui_tests, dashboard_tests).void_ok().boxed()
diff --git a/package.json b/package.json
index 354de7284fa..46370d905e8 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,8 @@
{
"devDependencies": {
+ "eslint-plugin-jsdoc": "^48.2.12",
+ "eslint-plugin-react-hooks": "^4.6.2",
+ "globals": "^15.8.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.2"
},
@@ -17,8 +20,8 @@
"ci-check": "run-p test prettier lint typecheck"
},
"workspaces": [
- "app/ide-desktop",
- "app/ide-desktop/lib/*",
+ "app/dashboard",
+ "app/ide-desktop/*",
"app/gui2",
"lib/js/runner"
],
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1bbb8dc4bab..f8c0cccd5bc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -25,6 +25,15 @@ importers:
specifier: ^5.5.3
version: 5.5.3
devDependencies:
+ eslint-plugin-jsdoc:
+ specifier: ^48.2.12
+ version: 48.5.2(eslint@8.57.0)
+ eslint-plugin-react-hooks:
+ specifier: ^4.6.2
+ version: 4.6.2(eslint@8.57.0)
+ globals:
+ specifier: ^15.8.0
+ version: 15.8.0
npm-run-all:
specifier: ^4.1.5
version: 4.1.5
@@ -32,6 +41,190 @@ importers:
specifier: ^3.3.2
version: 3.3.2
+ app/dashboard:
+ dependencies:
+ '@aws-amplify/auth':
+ specifier: 5.6.5
+ version: 5.6.5
+ '@aws-amplify/core':
+ specifier: 5.8.5
+ version: 5.8.5
+ '@hookform/resolvers':
+ specifier: ^3.4.0
+ version: 3.6.0(react-hook-form@7.52.0(react@18.3.1))
+ '@monaco-editor/react':
+ specifier: 4.6.0
+ version: 4.6.0(monaco-editor@0.48.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@sentry/react':
+ specifier: ^7.74.0
+ version: 7.118.0(react@18.3.1)
+ '@stripe/react-stripe-js':
+ specifier: ^2.7.1
+ version: 2.7.2(@stripe/stripe-js@3.5.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@stripe/stripe-js':
+ specifier: ^3.5.0
+ version: 3.5.0
+ '@tanstack/react-query':
+ specifier: 5.45.1
+ version: 5.45.1(react@18.3.1)
+ '@tanstack/vue-query':
+ specifier: '>= 5.45.0 < 5.46.0'
+ version: 5.45.0(vue@3.4.31(typescript@5.5.3))
+ ajv:
+ specifier: ^8.12.0
+ version: 8.16.0
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ enso-common:
+ specifier: workspace:*
+ version: link:../ide-desktop/common
+ is-network-error:
+ specifier: ^1.0.1
+ version: 1.1.0
+ monaco-editor:
+ specifier: 0.48.0
+ version: 0.48.0
+ react:
+ specifier: ^18.3.1
+ version: 18.3.1
+ react-aria:
+ specifier: ^3.33.0
+ version: 3.33.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react-aria-components:
+ specifier: ^1.2.0
+ version: 1.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react-dom:
+ specifier: ^18.3.1
+ version: 18.3.1(react@18.3.1)
+ react-error-boundary:
+ specifier: 4.0.13
+ version: 4.0.13(react@18.3.1)
+ react-hook-form:
+ specifier: ^7.51.4
+ version: 7.52.0(react@18.3.1)
+ react-router:
+ specifier: ^6.23.1
+ version: 6.24.0(react@18.3.1)
+ react-router-dom:
+ specifier: ^6.23.1
+ version: 6.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react-stately:
+ specifier: ^3.31.0
+ version: 3.31.1(react@18.3.1)
+ react-toastify:
+ specifier: ^9.1.3
+ version: 9.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ tailwind-merge:
+ specifier: ^2.3.0
+ version: 2.3.0
+ tailwind-variants:
+ specifier: 0.2.1
+ version: 0.2.1(tailwindcss@3.4.4)
+ tiny-invariant:
+ specifier: ^1.3.3
+ version: 1.3.3
+ ts-results:
+ specifier: ^3.3.0
+ version: 3.3.0
+ validator:
+ specifier: ^13.12.0
+ version: 13.12.0
+ zod:
+ specifier: ^3.23.8
+ version: 3.23.8
+ zustand:
+ specifier: ^4.5.4
+ version: 4.5.4(@types/react@18.3.3)(react@18.3.1)
+ devDependencies:
+ '@fast-check/vitest':
+ specifier: ^0.0.8
+ version: 0.0.8(vitest@1.6.0(@types/node@20.11.21)(jsdom@24.1.0)(lightningcss@1.25.1))
+ '@ianvs/prettier-plugin-sort-imports':
+ specifier: ^4.1.1
+ version: 4.3.0(@vue/compiler-sfc@3.4.31)(prettier@3.3.2)
+ '@modyfi/vite-plugin-yaml':
+ specifier: ^1.0.4
+ version: 1.1.0(rollup@4.18.1)(vite@5.3.3(@types/node@20.11.21)(lightningcss@1.25.1))
+ '@playwright/test':
+ specifier: ^1.40.0
+ version: 1.45.0
+ '@react-types/shared':
+ specifier: ^3.22.1
+ version: 3.23.1(react@18.3.1)
+ '@tanstack/react-query-devtools':
+ specifier: 5.45.1
+ version: 5.45.1(@tanstack/react-query@5.45.1(react@18.3.1))(react@18.3.1)
+ '@types/eslint__js':
+ specifier: ^8.42.3
+ version: 8.42.3
+ '@types/node':
+ specifier: ^20.11.21
+ version: 20.11.21
+ '@types/react':
+ specifier: ^18.0.27
+ version: 18.3.3
+ '@types/react-dom':
+ specifier: ^18.0.10
+ version: 18.3.0
+ '@types/validator':
+ specifier: ^13.11.7
+ version: 13.12.0
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^7.15.0
+ version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
+ '@typescript-eslint/parser':
+ specifier: ^7.15.0
+ version: 7.15.0(eslint@8.57.0)(typescript@5.5.3)
+ '@vitejs/plugin-react':
+ specifier: ^4.2.1
+ version: 4.3.1(vite@5.3.3(@types/node@20.11.21)(lightningcss@1.25.1))
+ chalk:
+ specifier: ^5.3.0
+ version: 5.3.0
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ enso-chat:
+ specifier: git://github.com/enso-org/enso-bot
+ version: enso-support@https://codeload.github.com/enso-org/enso-bot/tar.gz/aa903b6e639a31930ee4fff55c5639e4471fa48d
+ eslint:
+ specifier: ^8.49.0
+ version: 8.57.0
+ eslint-plugin-react:
+ specifier: ^7.32.1
+ version: 7.34.3(eslint@8.57.0)
+ fast-check:
+ specifier: ^3.15.0
+ version: 3.19.0
+ playwright:
+ specifier: ^1.38.0
+ version: 1.45.0
+ postcss:
+ specifier: ^8.4.29
+ version: 8.4.39
+ prettier-plugin-tailwindcss:
+ specifier: ^0.5.11
+ version: 0.5.14(@ianvs/prettier-plugin-sort-imports@4.3.0(@vue/compiler-sfc@3.4.31)(prettier@3.3.2))(prettier-plugin-organize-imports@4.0.0(prettier@3.3.2)(typescript@5.5.3))(prettier@3.3.2)
+ tailwindcss:
+ specifier: ^3.4.1
+ version: 3.4.4
+ tailwindcss-animate:
+ specifier: 1.0.7
+ version: 1.0.7(tailwindcss@3.4.4)
+ tailwindcss-react-aria-components:
+ specifier: ^1.1.1
+ version: 1.1.3(tailwindcss@3.4.4)
+ typescript:
+ specifier: ^5.5.3
+ version: 5.5.3
+ vite:
+ specifier: ^5.3.3
+ version: 5.3.3(@types/node@20.11.21)(lightningcss@1.25.1)
+ vitest:
+ specifier: ^1.3.1
+ version: 1.6.0(@types/node@20.11.21)(jsdom@24.1.0)(lightningcss@1.25.1)
+
app/gui2:
dependencies:
'@ag-grid-community/client-side-row-model':
@@ -135,7 +328,7 @@ importers:
version: 3.3.0
enso-dashboard:
specifier: workspace:*
- version: link:../ide-desktop/lib/dashboard
+ version: link:../dashboard
events:
specifier: ^3.3.0
version: 3.3.0
@@ -257,6 +450,9 @@ importers:
'@types/shuffle-seed':
specifier: ^1.1.0
version: 1.1.3
+ '@types/tar':
+ specifier: ^6.1.4
+ version: 6.1.13
'@types/unbzip2-stream':
specifier: ^1.4.3
version: 1.4.3
@@ -277,7 +473,7 @@ importers:
version: 1.6.0(vitest@1.6.0(@types/node@20.11.21)(jsdom@24.1.0)(lightningcss@1.25.1))
'@vue/eslint-config-prettier':
specifier: ^9.0.0
- version: 9.0.0(eslint@8.57.0)(prettier@3.3.2)
+ version: 9.0.0(@types/eslint@8.56.10)(eslint@8.57.0)(prettier@3.3.2)
'@vue/eslint-config-typescript':
specifier: ^13.0.0
version: 13.0.0(eslint-plugin-vue@9.26.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.5.3)
@@ -301,10 +497,7 @@ importers:
version: 7.9.0
enso-common:
specifier: workspace:*
- version: link:../ide-desktop/lib/common
- enso-project-manager-shim:
- specifier: workspace:*
- version: link:../ide-desktop/lib/project-manager-shim
+ version: link:../ide-desktop/common
eslint:
specifier: ^8.49.0
version: 8.57.0
@@ -348,7 +541,7 @@ importers:
specifier: ^3.2.7
version: 3.4.4
tar:
- specifier: ^6.2.0
+ specifier: ^6.2.1
version: 6.2.1
tsx:
specifier: ^4.7.1
@@ -374,78 +567,12 @@ importers:
vue-tsc:
specifier: ^2.0.24
version: 2.0.24(typescript@5.5.3)
+ yaml:
+ specifier: ^2.4.5
+ version: 2.4.5
- app/ide-desktop:
+ app/ide-desktop/client:
dependencies:
- '@stripe/react-stripe-js':
- specifier: ^2.3.1
- version: 2.7.2(@stripe/stripe-js@2.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@stripe/stripe-js':
- specifier: ^2.1.10
- version: 2.4.0
- esbuild-plugin-inline-image:
- specifier: ^0.0.9
- version: 0.0.9
- eslint-plugin-react:
- specifier: ^7.32.2
- version: 7.34.3(eslint@8.57.0)
- eslint-plugin-react-hooks:
- specifier: ^4.6.0
- version: 4.6.2(eslint@8.57.0)
- devDependencies:
- '@types/node':
- specifier: ^20.11.21
- version: 20.11.21
- '@types/react':
- specifier: ^18.0.27
- version: 18.3.3
- '@typescript-eslint/eslint-plugin':
- specifier: ^7.15.0
- version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
- '@typescript-eslint/parser':
- specifier: ^7.15.0
- version: 7.15.0(eslint@8.57.0)(typescript@5.5.3)
- cross-env:
- specifier: ^7.0.3
- version: 7.0.3
- esbuild:
- specifier: ^0.19.3
- version: 0.19.12
- eslint:
- specifier: ^8.49.0
- version: 8.57.0
- eslint-plugin-jsdoc:
- specifier: ^46.8.1
- version: 46.10.1(eslint@8.57.0)
- fast-check:
- specifier: ^3.15.0
- version: 3.19.0
- globals:
- specifier: ^14.0.0
- version: 14.0.0
- typescript:
- specifier: ^5.5.3
- version: 5.5.3
- vite:
- specifier: ^5.3.3
- version: 5.3.3(@types/node@20.11.21)(lightningcss@1.25.1)
-
- app/ide-desktop/lib/assets: {}
-
- app/ide-desktop/lib/client:
- dependencies:
- '@types/mime-types':
- specifier: ^2.1.1
- version: 2.1.4
- '@types/opener':
- specifier: ^1.4.0
- version: 1.4.3
- '@types/tar':
- specifier: ^6.1.4
- version: 6.1.13
- '@types/yargs':
- specifier: ^17.0.30
- version: 17.0.32
chalk:
specifier: ^5.2.0
version: 5.3.0
@@ -455,9 +582,6 @@ importers:
electron-is-dev:
specifier: ^2.0.0
version: 2.0.0
- enso-content-config:
- specifier: workspace:*
- version: link:../content-config
mime-types:
specifier: ^2.1.35
version: 2.1.35
@@ -467,6 +591,9 @@ importers:
opener:
specifier: ^1.5.2
version: 1.5.2
+ semver:
+ specifier: ^7.6.2
+ version: 7.6.2
string-length:
specifier: ^5.0.1
version: 5.0.1
@@ -483,9 +610,24 @@ importers:
'@electron/notarize':
specifier: 2.1.0
version: 2.1.0
+ '@types/mime-types':
+ specifier: ^2.1.1
+ version: 2.1.4
'@types/node':
specifier: ^20.11.21
version: 20.11.21
+ '@types/opener':
+ specifier: ^1.4.0
+ version: 1.4.3
+ '@types/semver':
+ specifier: ^7.5.8
+ version: 7.5.8
+ '@types/tar':
+ specifier: ^6.1.4
+ version: 6.1.13
+ '@types/yargs':
+ specifier: ^17.0.30
+ version: 17.0.32
electron:
specifier: 31.2.0
version: 31.2.0
@@ -495,12 +637,15 @@ importers:
enso-common:
specifier: workspace:*
version: link:../common
+ enso-dashboard:
+ specifier: workspace:*
+ version: link:../../dashboard
enso-gui2:
specifier: workspace:*
- version: link:../../../gui2
+ version: link:../../gui2
enso-runner:
specifier: workspace:*
- version: link:../../../../lib/js/runner
+ version: link:../../../lib/js/runner
esbuild:
specifier: ^0.19.3
version: 0.19.12
@@ -532,7 +677,7 @@ importers:
specifier: ^5.3.3
version: 5.3.3(@types/node@20.11.21)(lightningcss@1.25.1)
- app/ide-desktop/lib/common:
+ app/ide-desktop/common:
dependencies:
'@tanstack/query-core':
specifier: 5.45.0
@@ -553,221 +698,7 @@ importers:
specifier: ^3.4.19
version: 3.4.31(typescript@5.5.3)
- app/ide-desktop/lib/content-config:
- dependencies:
- '@types/semver':
- specifier: ^7.5.8
- version: 7.5.8
- enso-runner:
- specifier: workspace:*
- version: link:../../../../lib/js/runner
- semver:
- specifier: ^7.6.2
- version: 7.6.2
-
- app/ide-desktop/lib/dashboard:
- dependencies:
- '@aws-amplify/auth':
- specifier: 5.6.5
- version: 5.6.5
- '@aws-amplify/core':
- specifier: 5.8.5
- version: 5.8.5
- '@hookform/resolvers':
- specifier: ^3.4.0
- version: 3.6.0(react-hook-form@7.52.0(react@18.3.1))
- '@monaco-editor/react':
- specifier: 4.6.0
- version: 4.6.0(monaco-editor@0.48.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@sentry/react':
- specifier: ^7.74.0
- version: 7.118.0(react@18.3.1)
- '@tanstack/react-query':
- specifier: 5.45.1
- version: 5.45.1(react@18.3.1)
- '@tanstack/vue-query':
- specifier: '>= 5.45.0 < 5.46.0'
- version: 5.45.0(vue@3.4.31(typescript@5.5.3))
- ajv:
- specifier: ^8.12.0
- version: 8.16.0
- clsx:
- specifier: ^2.1.1
- version: 2.1.1
- enso-assets:
- specifier: workspace:*
- version: link:../assets
- enso-common:
- specifier: workspace:*
- version: link:../common
- is-network-error:
- specifier: ^1.0.1
- version: 1.1.0
- monaco-editor:
- specifier: 0.48.0
- version: 0.48.0
- react:
- specifier: ^18.3.1
- version: 18.3.1
- react-aria:
- specifier: ^3.33.0
- version: 3.33.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- react-aria-components:
- specifier: ^1.2.0
- version: 1.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- react-dom:
- specifier: ^18.3.1
- version: 18.3.1(react@18.3.1)
- react-error-boundary:
- specifier: 4.0.13
- version: 4.0.13(react@18.3.1)
- react-hook-form:
- specifier: ^7.51.4
- version: 7.52.0(react@18.3.1)
- react-router:
- specifier: ^6.23.1
- version: 6.24.0(react@18.3.1)
- react-router-dom:
- specifier: ^6.23.1
- version: 6.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- react-stately:
- specifier: ^3.31.0
- version: 3.31.1(react@18.3.1)
- react-toastify:
- specifier: ^9.1.3
- version: 9.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- tailwind-merge:
- specifier: ^2.3.0
- version: 2.3.0
- tailwind-variants:
- specifier: 0.2.1
- version: 0.2.1(tailwindcss@3.4.4)
- tiny-invariant:
- specifier: ^1.3.3
- version: 1.3.3
- ts-results:
- specifier: ^3.3.0
- version: 3.3.0
- validator:
- specifier: ^13.12.0
- version: 13.12.0
- zod:
- specifier: ^3.23.8
- version: 3.23.8
- zustand:
- specifier: ^4.5.4
- version: 4.5.4(@types/react@18.3.3)(react@18.3.1)
- devDependencies:
- '@esbuild-plugins/node-modules-polyfill':
- specifier: ^0.2.2
- version: 0.2.2(esbuild@0.19.12)
- '@fast-check/vitest':
- specifier: ^0.0.8
- version: 0.0.8(vitest@1.6.0(@types/node@20.11.21)(jsdom@24.1.0)(lightningcss@1.25.1))
- '@ianvs/prettier-plugin-sort-imports':
- specifier: ^4.1.1
- version: 4.3.0(@vue/compiler-sfc@3.4.31)(prettier@3.3.2)
- '@modyfi/vite-plugin-yaml':
- specifier: ^1.0.4
- version: 1.1.0(rollup@4.18.1)(vite@5.3.3(@types/node@20.11.21)(lightningcss@1.25.1))
- '@playwright/experimental-ct-react':
- specifier: ^1.40.0
- version: 1.45.0(@types/node@20.11.21)(lightningcss@1.25.1)(vite@5.3.3(@types/node@20.11.21)(lightningcss@1.25.1))
- '@playwright/test':
- specifier: ^1.40.0
- version: 1.45.0
- '@react-types/shared':
- specifier: ^3.22.1
- version: 3.23.1(react@18.3.1)
- '@tanstack/react-query-devtools':
- specifier: 5.45.1
- version: 5.45.1(@tanstack/react-query@5.45.1(react@18.3.1))(react@18.3.1)
- '@types/node':
- specifier: ^20.11.21
- version: 20.11.21
- '@types/react':
- specifier: ^18.0.27
- version: 18.3.3
- '@types/react-dom':
- specifier: ^18.0.10
- version: 18.3.0
- '@types/validator':
- specifier: ^13.11.7
- version: 13.12.0
- '@typescript-eslint/eslint-plugin':
- specifier: ^7.15.0
- version: 7.15.0(@typescript-eslint/parser@7.15.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)
- '@typescript-eslint/parser':
- specifier: ^7.15.0
- version: 7.15.0(eslint@8.57.0)(typescript@5.5.3)
- '@vitejs/plugin-react':
- specifier: ^4.2.1
- version: 4.3.1(vite@5.3.3(@types/node@20.11.21)(lightningcss@1.25.1))
- chalk:
- specifier: ^5.3.0
- version: 5.3.0
- cross-env:
- specifier: ^7.0.3
- version: 7.0.3
- enso-chat:
- specifier: git://github.com/enso-org/enso-bot
- version: enso-support@https://codeload.github.com/enso-org/enso-bot/tar.gz/aa903b6e639a31930ee4fff55c5639e4471fa48d
- esbuild:
- specifier: ^0.19.3
- version: 0.19.12
- esbuild-plugin-inline-image:
- specifier: ^0.0.9
- version: 0.0.9
- esbuild-plugin-time:
- specifier: ^1.0.0
- version: 1.0.0
- esbuild-plugin-yaml:
- specifier: ^0.0.1
- version: 0.0.1
- eslint:
- specifier: ^8.49.0
- version: 8.57.0
- eslint-plugin-jsdoc:
- specifier: ^46.8.1
- version: 46.10.1(eslint@8.57.0)
- eslint-plugin-react:
- specifier: ^7.32.1
- version: 7.34.3(eslint@8.57.0)
- fast-check:
- specifier: ^3.15.0
- version: 3.19.0
- playwright:
- specifier: ^1.38.0
- version: 1.45.0
- postcss:
- specifier: ^8.4.29
- version: 8.4.39
- prettier-plugin-tailwindcss:
- specifier: ^0.5.11
- version: 0.5.14(@ianvs/prettier-plugin-sort-imports@4.3.0(@vue/compiler-sfc@3.4.31)(prettier@3.3.2))(prettier-plugin-organize-imports@4.0.0(prettier@3.3.2)(typescript@5.5.3))(prettier@3.3.2)
- tailwindcss:
- specifier: ^3.4.1
- version: 3.4.4
- tailwindcss-animate:
- specifier: 1.0.7
- version: 1.0.7(tailwindcss@3.4.4)
- tailwindcss-react-aria-components:
- specifier: ^1.1.1
- version: 1.1.3(tailwindcss@3.4.4)
- ts-plugin-namespace-auto-import:
- specifier: workspace:*
- version: link:../ts-plugin-namespace-auto-import
- typescript:
- specifier: ^5.5.3
- version: 5.5.3
- vite:
- specifier: ^5.3.3
- version: 5.3.3(@types/node@20.11.21)(lightningcss@1.25.1)
- vitest:
- specifier: ^1.3.1
- version: 1.6.0(@types/node@20.11.21)(jsdom@24.1.0)(lightningcss@1.25.1)
-
- app/ide-desktop/lib/icons:
+ app/ide-desktop/icons:
devDependencies:
'@types/sharp':
specifier: ^0.31.1
@@ -782,27 +713,6 @@ importers:
specifier: ^1.1.5
version: 1.1.5
- app/ide-desktop/lib/project-manager-shim:
- dependencies:
- '@types/tar':
- specifier: ^6.1.4
- version: 6.1.13
- enso-common:
- specifier: workspace:*
- version: link:../common
- tar:
- specifier: ^6.2.0
- version: 6.2.1
- yaml:
- specifier: ^2.4.1
- version: 2.4.5
-
- app/ide-desktop/lib/ts-plugin-namespace-auto-import:
- devDependencies:
- typescript:
- specifier: ^5.5.3
- version: 5.5.3
-
lib/js/runner:
dependencies:
spectorjs:
@@ -1363,10 +1273,9 @@ packages:
resolution: {integrity: sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==}
engines: {node: '>=16'}
- '@esbuild-plugins/node-modules-polyfill@0.2.2':
- resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==}
- peerDependencies:
- esbuild: '*'
+ '@es-joy/jsdoccomment@0.43.1':
+ resolution: {integrity: sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==}
+ engines: {node: '>=16'}
'@esbuild/aix-ppc64@0.19.12':
resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==}
@@ -1917,15 +1826,6 @@ packages:
resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
- '@playwright/experimental-ct-core@1.45.0':
- resolution: {integrity: sha512-XxAZW3TnkkRlqRRiAnN/q8wzuspqDA2o8912TQkhbH2BKD3Ko4RLMVy0J7QJ+quG1fCp1/rlbg96/fB15wOemg==}
- engines: {node: '>=18'}
-
- '@playwright/experimental-ct-react@1.45.0':
- resolution: {integrity: sha512-GoT7eZMR5wLPFjGwQbGywiy2Z+9jwx5F+GJAZE1xbqMJPzSB5bv8zd5g09mWN4aKOHpc/kzkCBv0bxzW/es51A==}
- engines: {node: '>=18'}
- hasBin: true
-
'@playwright/test@1.45.0':
resolution: {integrity: sha512-TVYsfMlGAaxeUllNkywbwek67Ncf8FRGn8ZlRdO291OL3NjG9oMbfVhyP82HQF0CZLMrYsvesqoUekxdWuF9Qw==}
engines: {node: '>=18'}
@@ -2619,8 +2519,9 @@ packages:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
- '@stripe/stripe-js@2.4.0':
- resolution: {integrity: sha512-WFkQx1mbs2b5+7looI9IV1BLa3bIApuN3ehp9FP58xGg7KL9hCHDECgW3BwO9l9L+xBPVAD7Yjn1EhGe6EDTeA==}
+ '@stripe/stripe-js@3.5.0':
+ resolution: {integrity: sha512-pKS3wZnJoL1iTyGBXAvCwduNNeghJHY6QSRSNNvpYnrrQrLZ6Owsazjyynu0e0ObRgks0i7Rv+pe2M7/MBTZpQ==}
+ engines: {node: '>=12.16'}
'@swc/helpers@0.5.11':
resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==}
@@ -2789,6 +2690,12 @@ packages:
'@types/debug@4.1.12':
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+ '@types/eslint@8.56.10':
+ resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==}
+
+ '@types/eslint__js@8.42.3':
+ resolution: {integrity: sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==}
+
'@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
@@ -2813,6 +2720,9 @@ packages:
'@types/jsdom@21.1.7':
resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==}
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
'@types/keyv@3.1.4':
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
@@ -4156,6 +4066,9 @@ packages:
resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==}
engines: {node: '>= 0.4'}
+ es-module-lexer@1.5.4:
+ resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
+
es-object-atoms@1.0.0:
resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
engines: {node: '>= 0.4'}
@@ -4177,12 +4090,6 @@ packages:
es6-promise@3.3.1:
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
- esbuild-plugin-inline-image@0.0.9:
- resolution: {integrity: sha512-pw3ZgN2phh32Z7BpKrhRDtmI+iVCl+Gc0BLOT9croXg1MnMjRuN7aXhIQirhLeK39erkIwfFlhy6xieroBGc1Q==}
-
- esbuild-plugin-time@1.0.0:
- resolution: {integrity: sha512-I4Shhi0fpgXxSoc34djTHIuhbEzkcBbKKiNtb3LhZe2JEE1vSxXilW+KE0M/KZ4kqORLGgdGCKuJh9CNUL55yw==}
-
esbuild-plugin-yaml@0.0.1:
resolution: {integrity: sha512-s3jqOeeCd+dUuUsuBqLRgN2SeQjPF2ppIglvV3B//txgQpTDThGvxu6sqiOUOJ0NOzegitmpWCXoCONdRbUS7w==}
@@ -4223,6 +4130,12 @@ packages:
peerDependencies:
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
+ eslint-plugin-jsdoc@48.5.2:
+ resolution: {integrity: sha512-VXBJFviQz30rynlOEQ+dNWLmeopjoAgutUVrWOZwm6Ki4EVDm4XkyIqAV/Zhf7FcDr0AG0aGmRn5FxxCtAF0tA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
+
eslint-plugin-prettier@5.1.3:
resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -4297,9 +4210,6 @@ packages:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
- estree-walker@0.6.1:
- resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
-
estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
@@ -4585,6 +4495,10 @@ packages:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
+ globals@15.8.0:
+ resolution: {integrity: sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==}
+ engines: {node: '>=18'}
+
globalthis@1.0.3:
resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
engines: {node: '>= 0.4'}
@@ -5377,9 +5291,6 @@ packages:
magic-bytes.js@1.10.0:
resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==}
- magic-string@0.25.9:
- resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
-
magic-string@0.30.10:
resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
@@ -5765,6 +5676,10 @@ packages:
parse-headers@2.0.5:
resolution: {integrity: sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==}
+ parse-imports@2.1.1:
+ resolution: {integrity: sha512-TDT4HqzUiTMO1wJRwg/t/hYk8Wdp3iF/ToMIlAoVQfL1Xs/sTxq1dKWSMjMbQmIarfWKymOyly40+zmPHXMqCA==}
+ engines: {node: '>= 18'}
+
parse-json@4.0.0:
resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
engines: {node: '>=4'}
@@ -6321,16 +6236,6 @@ packages:
robust-predicates@3.0.2:
resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
- rollup-plugin-inject@3.0.2:
- resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==}
- deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.
-
- rollup-plugin-node-polyfills@0.2.1:
- resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==}
-
- rollup-pluginutils@2.8.2:
- resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
-
rollup@4.18.1:
resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
@@ -6493,6 +6398,9 @@ packages:
resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==}
engines: {node: '>=12'}
+ slashes@3.0.12:
+ resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==}
+
slice-ansi@3.0.0:
resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==}
engines: {node: '>=8'}
@@ -6515,10 +6423,6 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
- sourcemap-codec@1.4.8:
- resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
- deprecated: Please use @jridgewell/sourcemap-codec instead
-
spdx-correct@3.2.0:
resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
@@ -6694,6 +6598,10 @@ packages:
resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==}
engines: {node: ^14.18.0 || >=16.0.0}
+ synckit@0.9.0:
+ resolution: {integrity: sha512-7RnqIMq572L8PeEzKeBINYEJDDxpcH8JEgLwUqBd3TkofhFRbkq4QLR0u+36avGAhCRbk2nnmjcW9SE531hPDg==}
+ engines: {node: ^14.18.0 || >=16.0.0}
+
tailwind-merge@2.3.0:
resolution: {integrity: sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==}
@@ -8204,11 +8112,14 @@ snapshots:
esquery: 1.5.0
jsdoc-type-pratt-parser: 4.0.0
- '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.19.12)':
+ '@es-joy/jsdoccomment@0.43.1':
dependencies:
- esbuild: 0.19.12
- escape-string-regexp: 4.0.0
- rollup-plugin-node-polyfills: 0.2.1
+ '@types/eslint': 8.56.10
+ '@types/estree': 1.0.5
+ '@typescript-eslint/types': 7.15.0
+ comment-parser: 1.4.1
+ esquery: 1.5.0
+ jsdoc-type-pratt-parser: 4.0.0
'@esbuild/aix-ppc64@0.19.12':
optional: true
@@ -8779,35 +8690,6 @@ snapshots:
'@pkgr/core@0.1.1': {}
- '@playwright/experimental-ct-core@1.45.0(@types/node@20.11.21)(lightningcss@1.25.1)':
- dependencies:
- playwright: 1.45.0
- playwright-core: 1.45.0
- vite: 5.3.3(@types/node@20.11.21)(lightningcss@1.25.1)
- transitivePeerDependencies:
- - '@types/node'
- - less
- - lightningcss
- - sass
- - stylus
- - sugarss
- - terser
-
- '@playwright/experimental-ct-react@1.45.0(@types/node@20.11.21)(lightningcss@1.25.1)(vite@5.3.3(@types/node@20.11.21)(lightningcss@1.25.1))':
- dependencies:
- '@playwright/experimental-ct-core': 1.45.0(@types/node@20.11.21)(lightningcss@1.25.1)
- '@vitejs/plugin-react': 4.3.1(vite@5.3.3(@types/node@20.11.21)(lightningcss@1.25.1))
- transitivePeerDependencies:
- - '@types/node'
- - less
- - lightningcss
- - sass
- - stylus
- - sugarss
- - supports-color
- - terser
- - vite
-
'@playwright/test@1.45.0':
dependencies:
playwright: 1.45.0
@@ -9879,14 +9761,14 @@ snapshots:
'@smithy/util-buffer-from': 2.2.0
tslib: 2.6.3
- '@stripe/react-stripe-js@2.7.2(@stripe/stripe-js@2.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ '@stripe/react-stripe-js@2.7.2(@stripe/stripe-js@3.5.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@stripe/stripe-js': 2.4.0
+ '@stripe/stripe-js': 3.5.0
prop-types: 15.8.1
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- '@stripe/stripe-js@2.4.0': {}
+ '@stripe/stripe-js@3.5.0': {}
'@swc/helpers@0.5.11':
dependencies:
@@ -10086,6 +9968,15 @@ snapshots:
dependencies:
'@types/ms': 0.7.34
+ '@types/eslint@8.56.10':
+ dependencies:
+ '@types/estree': 1.0.5
+ '@types/json-schema': 7.0.15
+
+ '@types/eslint__js@8.42.3':
+ dependencies:
+ '@types/eslint': 8.56.10
+
'@types/estree@1.0.5': {}
'@types/flexsearch@0.7.6': {}
@@ -10108,6 +9999,8 @@ snapshots:
'@types/tough-cookie': 4.0.5
parse5: 7.1.2
+ '@types/json-schema@7.0.15': {}
+
'@types/keyv@3.1.4':
dependencies:
'@types/node': 20.11.21
@@ -10468,11 +10361,11 @@ snapshots:
dependencies:
rfdc: 1.4.1
- '@vue/eslint-config-prettier@9.0.0(eslint@8.57.0)(prettier@3.3.2)':
+ '@vue/eslint-config-prettier@9.0.0(@types/eslint@8.56.10)(eslint@8.57.0)(prettier@3.3.2)':
dependencies:
eslint: 8.57.0
eslint-config-prettier: 9.1.0(eslint@8.57.0)
- eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2)
+ eslint-plugin-prettier: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2)
prettier: 3.3.2
transitivePeerDependencies:
- '@types/eslint'
@@ -11839,6 +11732,8 @@ snapshots:
iterator.prototype: 1.1.2
safe-array-concat: 1.1.2
+ es-module-lexer@1.5.4: {}
+
es-object-atoms@1.0.0:
dependencies:
es-errors: 1.3.0
@@ -11864,12 +11759,6 @@ snapshots:
es6-promise@3.3.1: {}
- esbuild-plugin-inline-image@0.0.9: {}
-
- esbuild-plugin-time@1.0.0:
- dependencies:
- chalk: 4.1.2
-
esbuild-plugin-yaml@0.0.1:
dependencies:
fs-extra: 9.1.0
@@ -11954,13 +11843,30 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2):
+ eslint-plugin-jsdoc@48.5.2(eslint@8.57.0):
+ dependencies:
+ '@es-joy/jsdoccomment': 0.43.1
+ are-docs-informative: 0.0.2
+ comment-parser: 1.4.1
+ debug: 4.3.5
+ escape-string-regexp: 4.0.0
+ eslint: 8.57.0
+ esquery: 1.5.0
+ parse-imports: 2.1.1
+ semver: 7.6.2
+ spdx-expression-parse: 4.0.0
+ synckit: 0.9.0
+ transitivePeerDependencies:
+ - supports-color
+
+ eslint-plugin-prettier@5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.2):
dependencies:
eslint: 8.57.0
prettier: 3.3.2
prettier-linter-helpers: 1.0.0
synckit: 0.8.8
optionalDependencies:
+ '@types/eslint': 8.56.10
eslint-config-prettier: 9.1.0(eslint@8.57.0)
eslint-plugin-react-hooks@4.6.2(eslint@8.57.0):
@@ -12079,8 +11985,6 @@ snapshots:
estraverse@5.3.0: {}
- estree-walker@0.6.1: {}
-
estree-walker@2.0.2: {}
estree-walker@3.0.3:
@@ -12391,6 +12295,8 @@ snapshots:
globals@14.0.0: {}
+ globals@15.8.0: {}
+
globalthis@1.0.3:
dependencies:
define-properties: 1.2.1
@@ -13256,10 +13162,6 @@ snapshots:
magic-bytes.js@1.10.0: {}
- magic-string@0.25.9:
- dependencies:
- sourcemap-codec: 1.4.8
-
magic-string@0.30.10:
dependencies:
'@jridgewell/sourcemap-codec': 1.4.15
@@ -13620,6 +13522,11 @@ snapshots:
parse-headers@2.0.5: {}
+ parse-imports@2.1.1:
+ dependencies:
+ es-module-lexer: 1.5.4
+ slashes: 3.0.12
+
parse-json@4.0.0:
dependencies:
error-ex: 1.3.2
@@ -13813,12 +13720,6 @@ snapshots:
dependencies:
fast-diff: 1.3.0
- prettier-plugin-organize-imports@4.0.0(prettier@3.3.2)(typescript@5.5.3):
- dependencies:
- prettier: 3.3.2
- typescript: 5.5.3
- optional: true
-
prettier-plugin-organize-imports@4.0.0(prettier@3.3.2)(typescript@5.5.3)(vue-tsc@2.0.24(typescript@5.5.3)):
dependencies:
prettier: 3.3.2
@@ -13831,7 +13732,7 @@ snapshots:
prettier: 3.3.2
optionalDependencies:
'@ianvs/prettier-plugin-sort-imports': 4.3.0(@vue/compiler-sfc@3.4.31)(prettier@3.3.2)
- prettier-plugin-organize-imports: 4.0.0(prettier@3.3.2)(typescript@5.5.3)
+ prettier-plugin-organize-imports: 4.0.0(prettier@3.3.2)(typescript@5.5.3)(vue-tsc@2.0.24(typescript@5.5.3))
prettier@3.3.2: {}
@@ -14213,20 +14114,6 @@ snapshots:
robust-predicates@3.0.2: {}
- rollup-plugin-inject@3.0.2:
- dependencies:
- estree-walker: 0.6.1
- magic-string: 0.25.9
- rollup-pluginutils: 2.8.2
-
- rollup-plugin-node-polyfills@0.2.1:
- dependencies:
- rollup-plugin-inject: 3.0.2
-
- rollup-pluginutils@2.8.2:
- dependencies:
- estree-walker: 0.6.1
-
rollup@4.18.1:
dependencies:
'@types/estree': 1.0.5
@@ -14411,6 +14298,8 @@ snapshots:
slash@4.0.0: {}
+ slashes@3.0.12: {}
+
slice-ansi@3.0.0:
dependencies:
ansi-styles: 4.3.0
@@ -14435,8 +14324,6 @@ snapshots:
source-map@0.6.1: {}
- sourcemap-codec@1.4.8: {}
-
spdx-correct@3.2.0:
dependencies:
spdx-expression-parse: 3.0.1
@@ -14634,6 +14521,11 @@ snapshots:
'@pkgr/core': 0.1.1
tslib: 2.6.3
+ synckit@0.9.0:
+ dependencies:
+ '@pkgr/core': 0.1.1
+ tslib: 2.6.3
+
tailwind-merge@2.3.0:
dependencies:
'@babel/runtime': 7.24.7
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 002edd5ed6e..52388c5e3f4 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,5 +1,5 @@
packages:
- - app/ide-desktop
- - app/ide-desktop/lib/*
+ - app/dashboard
+ - app/ide-desktop/*
- app/gui2
- lib/js/runner