From eb4fb891a81e3f92b8828cf7f112808022b8d8dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:27:58 -0800 Subject: [PATCH 01/35] Bump the dev-dependencies group across 1 directory with 6 updates (#1515) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the dev-dependencies group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.10.1` | `22.10.2` | | [@types/prop-types](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/prop-types) | `15.7.13` | `15.7.14` | | [sass](https://github.com/sass/dart-sass) | `1.82.0` | `1.83.0` | | [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.17.0` | `8.18.0` | | [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `6.0.2` | `6.0.3` | | [vite-tsconfig-paths](https://github.com/aleclarson/vite-tsconfig-paths) | `5.1.3` | `5.1.4` | Updates `@types/node` from 22.10.1 to 22.10.2
Commits

Updates `@types/prop-types` from 15.7.13 to 15.7.14
Commits

Updates `sass` from 1.82.0 to 1.83.0
Release notes

Sourced from sass's releases.

Dart Sass 1.83.0

To install Sass 1.83.0, download one of the packages below and add it to your PATH, or see the Sass website for full installation instructions.

Changes

See the full changelog for changes in earlier releases.

Changelog

Sourced from sass's changelog.

1.83.0

Commits

Updates `typescript-eslint` from 8.17.0 to 8.18.0
Release notes

Sourced from typescript-eslint's releases.

v8.18.0

8.18.0 (2024-12-09)

🚀 Features

đź©ą Fixes

❤️ Thank You

You can read about our versioning strategy and releases on our website.

Changelog

Sourced from typescript-eslint's changelog.

8.18.0 (2024-12-09)

đź©ą Fixes

❤️ Thank You

You can read about our versioning strategy and releases on our website.

Commits

Updates `vite` from 6.0.2 to 6.0.3
Release notes

Sourced from vite's releases.

v6.0.3

Please refer to CHANGELOG.md for details.

Changelog

Sourced from vite's changelog.

6.0.3 (2024-12-05)

Commits

Updates `vite-tsconfig-paths` from 5.1.3 to 5.1.4
Release notes

Sourced from vite-tsconfig-paths's releases.

v5.1.4

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/package.json | 2 +- package.json | 10 +-- yarn.lock | 189 ++++++++++++++++++++++------------------------ 3 files changed, 95 insertions(+), 106 deletions(-) diff --git a/docs/package.json b/docs/package.json index d86e9b505..792182646 100644 --- a/docs/package.json +++ b/docs/package.json @@ -53,7 +53,7 @@ "remark-preset-lint-consistent": "^6.0.0", "remark-preset-lint-recommended": "^7.0.0", "typescript": "^5.7.2", - "typescript-eslint": "^8.17.0" + "typescript-eslint": "^8.18.0" }, "resolutions": { "path-to-regexp@npm:2.2.1": "^3", diff --git a/package.json b/package.json index c0a22c98d..3232e4a1b 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@types/css-tree": "^2", "@types/debug": "^4", "@types/electron": "^1.6.12", - "@types/node": "^22.10.1", + "@types/node": "^22.10.2", "@types/papaparse": "^5", "@types/pngjs": "^6.0.5", "@types/prop-types": "^15", @@ -67,7 +67,7 @@ "prettier-plugin-jsdoc": "^1.3.0", "prettier-plugin-organize-imports": "^4.1.0", "rollup-plugin-flow": "^1.1.1", - "sass": "^1.82.0", + "sass": "^1.83.0", "semver": "^7.6.3", "storybook": "^8.4.7", "storybook-dark-mode": "^4.0.2", @@ -75,12 +75,12 @@ "tslib": "^2.8.1", "tsx": "^4.19.2", "typescript": "^5.7.2", - "typescript-eslint": "^8.17.0", - "vite": "^6.0.2", + "typescript-eslint": "^8.18.0", + "vite": "^6.0.3", "vite-plugin-image-optimizer": "^1.1.8", "vite-plugin-static-copy": "^2.2.0", "vite-plugin-svgr": "^4.3.0", - "vite-tsconfig-paths": "^5.1.3", + "vite-tsconfig-paths": "^5.1.4", "vitest": "^2.1.8" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index 1e781e778..6fe0eaa92 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6450,12 +6450,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^22.10.1": - version: 22.10.1 - resolution: "@types/node@npm:22.10.1" +"@types/node@npm:^22.10.2": + version: 22.10.2 + resolution: "@types/node@npm:22.10.2" dependencies: undici-types: "npm:~6.20.0" - checksum: 10c0/0fbb6d29fa35d807f0223a4db709c598ac08d66820240a2cd6a8a69b8f0bc921d65b339d850a666b43b4e779f967e6ed6cf6f0fca3575e08241e6b900364c234 + checksum: 10c0/2c7b71a040f1ef5320938eca8ebc946e6905caa9bbf3d5665d9b3774a8d15ea9fab1582b849a6d28c7fc80756a62c5666bc66b69f42f4d5dafd1ccb193cdb4ac languageName: node linkType: hard @@ -6502,9 +6502,9 @@ __metadata: linkType: hard "@types/prop-types@npm:*, @types/prop-types@npm:^15": - version: 15.7.13 - resolution: "@types/prop-types@npm:15.7.13" - checksum: 10c0/1b20fc67281902c6743379960247bc161f3f0406ffc0df8e7058745a85ea1538612109db0406290512947f9632fe9e10e7337bf0ce6338a91d6c948df16a7c61 + version: 15.7.14 + resolution: "@types/prop-types@npm:15.7.14" + checksum: 10c0/1ec775160bfab90b67a782d735952158c7e702ca4502968aa82565bd8e452c2de8601c8dfe349733073c31179116cf7340710160d3836aa8a1ef76d1532893b1 languageName: node linkType: hard @@ -6793,15 +6793,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.17.0" +"@typescript-eslint/eslint-plugin@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.18.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.17.0" - "@typescript-eslint/type-utils": "npm:8.17.0" - "@typescript-eslint/utils": "npm:8.17.0" - "@typescript-eslint/visitor-keys": "npm:8.17.0" + "@typescript-eslint/scope-manager": "npm:8.18.0" + "@typescript-eslint/type-utils": "npm:8.18.0" + "@typescript-eslint/utils": "npm:8.18.0" + "@typescript-eslint/visitor-keys": "npm:8.18.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -6809,108 +6809,99 @@ __metadata: peerDependencies: "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/d78778173571a9a1370345bc2aa3e850235a489d16b8a8b5ba3086b988bbef7549bdae38e509d7a679ba3179c688cc5a408376b158be402770836e94ffc9602d + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/c338da1b96c41d7b94401a6711659d0fef3acb691eff7a958f9d3aa0442a858830daad67e3575288a4f4669572e2b690517a513519b404a465ad68fe0a82d3ec languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/parser@npm:8.17.0" +"@typescript-eslint/parser@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/parser@npm:8.18.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.17.0" - "@typescript-eslint/types": "npm:8.17.0" - "@typescript-eslint/typescript-estree": "npm:8.17.0" - "@typescript-eslint/visitor-keys": "npm:8.17.0" + "@typescript-eslint/scope-manager": "npm:8.18.0" + "@typescript-eslint/types": "npm:8.18.0" + "@typescript-eslint/typescript-estree": "npm:8.18.0" + "@typescript-eslint/visitor-keys": "npm:8.18.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/2543deadf01302a92d3b6f58a4c14f98d8936c4d976e7da05e3bb65608f19d8de93b25282e343c304eca3e3f37f2ac23e97fa9c11c6edff36dd2d4f6b601a630 + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/d3a062511c24dfcf522a645db1153022d49aa3bb05e288c22474cf04dc1d836f877eb9d2733947e448981ffb16e4de50d4ebe7570a268733a641f228ca6c4849 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/scope-manager@npm:8.17.0" +"@typescript-eslint/scope-manager@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/scope-manager@npm:8.18.0" dependencies: - "@typescript-eslint/types": "npm:8.17.0" - "@typescript-eslint/visitor-keys": "npm:8.17.0" - checksum: 10c0/0c08d14240bad4b3f6874f08ba80b29db1a6657437089a6f109db458c544d835bcdc06ba9140bb4f835233ba4326d9a86e6cf6bdb5209960d2f7025aa3191f4f + "@typescript-eslint/types": "npm:8.18.0" + "@typescript-eslint/visitor-keys": "npm:8.18.0" + checksum: 10c0/6bf6532fd43f2b55b9b47fa8b0217c5b5a03f022e869a6a21228fc3ae04c0ac6c5ae5d6026866d189ba424d2f98cc6fbd2a34f909d241c9b86c031afd808f90c languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/type-utils@npm:8.17.0" +"@typescript-eslint/type-utils@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/type-utils@npm:8.18.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.17.0" - "@typescript-eslint/utils": "npm:8.17.0" + "@typescript-eslint/typescript-estree": "npm:8.18.0" + "@typescript-eslint/utils": "npm:8.18.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/6138ec71b5692d4b5e0bf3d7f66a6fa4e91ddea7031907b0ac45a7693df0a2f4cc5bca7218311e0639620d636ceb7efec83a137dfcd5938304d873b774fcc8bd + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/c0fcf201c3b53f9374c0571198a639c81536170141caa08fd0f47094a596b1f82f839a849eac5832f954345c567dccb45b2ee1c0872c513331165f7bcb812396 languageName: node linkType: hard -"@typescript-eslint/types@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/types@npm:8.17.0" - checksum: 10c0/26b1bf9dfc3ee783c85c6f354b84c28706d5689d777f3ff2de2cb496e45f9d0189c0d561c03ccbc8b24712438be17cf63dd0871ff3ca2083e7f48749770d1893 +"@typescript-eslint/types@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/types@npm:8.18.0" + checksum: 10c0/2dd7468c3f1c305545268b72c3a333488e6ab1b628c5f65081d895866422b9376c21634a7aac437805f84b22e352b6a8fc4dcf925ef4a8fd7d1898b8359f71be languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.17.0" +"@typescript-eslint/typescript-estree@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.18.0" dependencies: - "@typescript-eslint/types": "npm:8.17.0" - "@typescript-eslint/visitor-keys": "npm:8.17.0" + "@typescript-eslint/types": "npm:8.18.0" + "@typescript-eslint/visitor-keys": "npm:8.18.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" minimatch: "npm:^9.0.4" semver: "npm:^7.6.0" ts-api-utils: "npm:^1.3.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/523013f9b5cf2c58c566868e4c3b0b9ac1b4807223a6d64e2a7c58e01e53b6587ba61f1a8241eade361f3f426d6057657515473176141ef8aebb352bc0d223ce + peerDependencies: + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/87b432b190b627314f007b17b2371898db78baaa3df67a0d9a94d080d88a7a307906b54a735084cacef37f6421e2b9c3320040617e73fe54eac2bf22c610f1ec languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/utils@npm:8.17.0" +"@typescript-eslint/utils@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/utils@npm:8.18.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.17.0" - "@typescript-eslint/types": "npm:8.17.0" - "@typescript-eslint/typescript-estree": "npm:8.17.0" + "@typescript-eslint/scope-manager": "npm:8.18.0" + "@typescript-eslint/types": "npm:8.18.0" + "@typescript-eslint/typescript-estree": "npm:8.18.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/a9785ae5f7e7b51d521dc3f48b15093948e4fcd03352c0b60f39bae366cbc935947d215f91e2ae3182d52fa6affb5ccbb50feff487bd1209011f3e0da02cdf07 + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/58a2fc1e404d1f905c2a958d995824eb4abc6e73836b186717550677f8b1d17954acc369feddb83277350915388bc3d8b721423c37777b8b8017fc29c89ec6ee languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.17.0": - version: 8.17.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.17.0" +"@typescript-eslint/visitor-keys@npm:8.18.0": + version: 8.18.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.18.0" dependencies: - "@typescript-eslint/types": "npm:8.17.0" + "@typescript-eslint/types": "npm:8.18.0" eslint-visitor-keys: "npm:^4.2.0" - checksum: 10c0/9144c4e4a63034fb2031a0ee1fc77e80594f30cab3faafa9a1f7f83782695774dd32fac8986f260698b4e150b4dd52444f2611c07e4c101501f08353eb47c82c + checksum: 10c0/d4cdc2adab553098b5be7117fb7df76fb66cfd380528881a0a8c2a9eee03bf8baddda07d15ca0bd3ed8b35c379b3f449292183df18e3e81898dbcadafcb708b8 languageName: node linkType: hard @@ -19358,9 +19349,9 @@ __metadata: languageName: node linkType: hard -"sass@npm:^1.82.0": - version: 1.82.0 - resolution: "sass@npm:1.82.0" +"sass@npm:^1.83.0": + version: 1.83.0 + resolution: "sass@npm:1.83.0" dependencies: "@parcel/watcher": "npm:^2.4.1" chokidar: "npm:^4.0.0" @@ -19371,7 +19362,7 @@ __metadata: optional: true bin: sass: sass.js - checksum: 10c0/7f86fe6ade4f6018862c448ed69d5c52f485b0125c9dab24e63f679739a04cc7c56562d588e3cf16b5efb4d2c4d0530e62740e1cfd273e2e3707d04d11011736 + checksum: 10c0/4415361229879a9041d77c953da85482e89032aa4321ba13250a9987d39c80fac6c88af3777f2a2d76a4e8b0c8afbd21c1970fdbe84e0b3ec25fb26741f92beb languageName: node linkType: hard @@ -20962,19 +20953,17 @@ __metadata: languageName: node linkType: hard -"typescript-eslint@npm:^8.17.0": - version: 8.17.0 - resolution: "typescript-eslint@npm:8.17.0" +"typescript-eslint@npm:^8.18.0": + version: 8.18.0 + resolution: "typescript-eslint@npm:8.18.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.17.0" - "@typescript-eslint/parser": "npm:8.17.0" - "@typescript-eslint/utils": "npm:8.17.0" + "@typescript-eslint/eslint-plugin": "npm:8.18.0" + "@typescript-eslint/parser": "npm:8.18.0" + "@typescript-eslint/utils": "npm:8.18.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/b148525769b9afa789ad3c2d52249fa78e67a225d48d17f2f0117b0e8b52566112be3a35de6cd26bcaffba3114be87c1070f7f4b4e2b730c059668fec4a530bc + typescript: ">=4.8.4 <5.8.0" + checksum: 10c0/dda882cbfc1ebad6903864571bc69bfd7e32e17fec67d98fdfab2bd652348d425c6a1c3697734d59cd5dd15d26d496db3c3808c1de5840fa29b9e76184fa1865 languageName: node linkType: hard @@ -21675,9 +21664,9 @@ __metadata: languageName: node linkType: hard -"vite-tsconfig-paths@npm:^5.1.3": - version: 5.1.3 - resolution: "vite-tsconfig-paths@npm:5.1.3" +"vite-tsconfig-paths@npm:^5.1.4": + version: 5.1.4 + resolution: "vite-tsconfig-paths@npm:5.1.4" dependencies: debug: "npm:^4.1.1" globrex: "npm:^0.1.2" @@ -21687,7 +21676,7 @@ __metadata: peerDependenciesMeta: vite: optional: true - checksum: 10c0/fb7480efa31fd50439f4a12c91bc953e5cc09d69fdc7eeb6ffff7cc796bc2c1f2c617c3abfdcbf5d7414848076cea9deb60bc002142f93b6e3131e5458760710 + checksum: 10c0/6228f23155ea25d92b1e1702284cf8dc52ad3c683c5ca691edd5a4c82d2913e7326d00708cef1cbfde9bb226261df0e0a12e03ef1d43b6a92d8f02b483ef37e3 languageName: node linkType: hard @@ -21734,9 +21723,9 @@ __metadata: languageName: node linkType: hard -"vite@npm:^6.0.2": - version: 6.0.2 - resolution: "vite@npm:6.0.2" +"vite@npm:^6.0.3": + version: 6.0.3 + resolution: "vite@npm:6.0.3" dependencies: esbuild: "npm:^0.24.0" fsevents: "npm:~2.3.3" @@ -21782,7 +21771,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/45fc609f2bc5fb5beb5a8e2cad9ad6c2edce229a922f6fc1270ea2a9d75819482edcc0f77c85b4a7abdad7eb69ce6a4f26131925d47cdc0778fc15d1bbc3b6a2 + checksum: 10c0/764ebed14770426a638575b23a51127c630ace873999ab896b0184484d8107e7255cdf64cfb36c65c1ef1d583e44b70a1d14c0f05b89612e834a5806e3964475 languageName: node linkType: hard @@ -21937,7 +21926,7 @@ __metadata: remark-preset-lint-recommended: "npm:^7.0.0" remark-typescript-code-import: "npm:^1.0.1" typescript: "npm:^5.7.2" - typescript-eslint: "npm:^8.17.0" + typescript-eslint: "npm:^8.18.0" ua-parser-js: "npm:^2.0.0" languageName: unknown linkType: soft @@ -21970,7 +21959,7 @@ __metadata: "@types/css-tree": "npm:^2" "@types/debug": "npm:^4" "@types/electron": "npm:^1.6.12" - "@types/node": "npm:^22.10.1" + "@types/node": "npm:^22.10.2" "@types/papaparse": "npm:^5" "@types/pngjs": "npm:^6.0.5" "@types/prop-types": "npm:^15" @@ -22035,7 +22024,7 @@ __metadata: remark-github-blockquote-alert: "npm:^1.3.0" rollup-plugin-flow: "npm:^1.1.1" rxjs: "npm:^7.8.1" - sass: "npm:^1.82.0" + sass: "npm:^1.83.0" semver: "npm:^7.6.3" sharp: "npm:^0.33.5" shell-quote: "npm:^1.8.2" @@ -22048,13 +22037,13 @@ __metadata: tslib: "npm:^2.8.1" tsx: "npm:^4.19.2" typescript: "npm:^5.7.2" - typescript-eslint: "npm:^8.17.0" + typescript-eslint: "npm:^8.18.0" use-device-pixel-ratio: "npm:^1.1.2" - vite: "npm:^6.0.2" + vite: "npm:^6.0.3" vite-plugin-image-optimizer: "npm:^1.1.8" vite-plugin-static-copy: "npm:^2.2.0" vite-plugin-svgr: "npm:^4.3.0" - vite-tsconfig-paths: "npm:^5.1.3" + vite-tsconfig-paths: "npm:^5.1.4" vitest: "npm:^2.1.8" winston: "npm:^3.17.0" ws: "npm:^8.18.0" From e6ee15ba907fa1ef6b076218cc6f5038c8c1826a Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Mon, 16 Dec 2024 13:57:37 -0800 Subject: [PATCH 02/35] readme updates (#1533) --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8af65d91a..529fdee26 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,23 @@ [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwavetermdev%2Fwaveterm.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fwavetermdev%2Fwaveterm?ref=badge_shield) [![waveterm](https://snapcraft.io/waveterm/trending.svg?name=0)](https://snapcraft.io/waveterm) -Wave is an open-source terminal that can launch graphical widgets, controlled and integrated directly with the CLI. It includes a base terminal, directory browser, file previews (images, media, markdown), a graphical editor (for code/text files), a web browser, and integrated AI chat. +Wave is an open-source terminal that combines traditional terminal features with graphical capabilities like file previews, web browsing, and AI assistance. It runs on MacOS, Linux, and Windows. -Wave isn't just another terminal emulator; it's a rethink on how terminals are built. For too long there has been a disconnect between the CLI and the web. If you want fast, keyboard-accessible, easy-to-write applications, you use the CLI, but if you want graphical interfaces, native widgets, copy/paste, scrolling, variable font sizes, then you'd have to turn to the web. Wave's goal is to bridge that gap. +Modern development involves constantly switching between terminals and browsers - checking documentation, previewing files, monitoring systems, and using AI tools. Wave brings these graphical tools directly into the terminal, letting you control them from the command line. This means you can stay in your terminal workflow while still having access to the visual interfaces you need. ![WaveTerm Screenshot](./assets/wave-screenshot.webp) +## Key Features + +- Flexible drag & drop interface to organize terminal blocks, editors, web browsers, and AI assistants +- Built-in editor for seamlessly editing remote files with syntax highlighting and modern editor features +- Rich file preview system for remote files (markdown, images, video, PDFs, CSVs, directories) +- Integrated AI chat with support for multiple models (OpenAI, Claude, Azure, Perplexity, Ollama) +- Command Blocks for isolating and monitoring individual commands with auto-close options +- One-click remote connections with full terminal and file system access +- Rich customization including tab themes, terminal styles, and background images +- Powerful `wsh` command system for managing your workspace from the CLI and sharing data between terminal sessions + ## Installation Wave Terminal works on macOS, Linux, and Windows. @@ -43,6 +54,7 @@ Wave Terminal and WSH run on the following platforms: - Documentation — https://docs.waveterm.dev - Legacy Documentation — https://legacydocs.waveterm.dev - Blog — https://blog.waveterm.dev +- X — https://x.com/wavetermdev - Discord Community — https://discord.gg/XfvZ334gwU ## Building from Source From 2285ac99db0a9f209719071bf3f59fe237216d69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:04:10 -0800 Subject: [PATCH 03/35] Bump github.com/shirou/gopsutil/v4 from 4.24.10 to 4.24.11 (#1410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/shirou/gopsutil/v4](https://github.com/shirou/gopsutil) from 4.24.10 to 4.24.11.
Release notes

Sourced from github.com/shirou/gopsutil/v4's releases.

v4.24.11

What's Changed

host

New Contributors

Full Changelog: https://github.com/shirou/gopsutil/compare/v4.24.10...v4.24.11

Commits
  • 62a52f9 Merge pull request #1745 from wangyu-geek/add_anolis_family_in_host_linux
  • 8e62971 add anolis family with anolis platform
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/shirou/gopsutil/v4&package-manager=go_modules&previous-version=4.24.10&new-version=4.24.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 01c4fe6f8..c713a76c6 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/sashabaranov/go-openai v1.36.0 github.com/sawka/txwrap v0.2.0 - github.com/shirou/gopsutil/v4 v4.24.10 + github.com/shirou/gopsutil/v4 v4.24.11 github.com/skeema/knownhosts v1.3.0 github.com/spf13/cobra v1.8.1 github.com/ubuntu/gowsl v0.0.0-20240906163211-049fd49bd93b diff --git a/go.sum b/go.sum index d9c045d79..b59c00510 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/sashabaranov/go-openai v1.36.0 h1:fcSrn8uGuorzPWCBp8L0aCR95Zjb/Dd+ZSM github.com/sashabaranov/go-openai v1.36.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/sawka/txwrap v0.2.0 h1:V3LfvKVLULxcYSxdMguLwFyQFMEU9nFDJopg0ZkL+94= github.com/sawka/txwrap v0.2.0/go.mod h1:wwQ2SQiN4U+6DU/iVPhbvr7OzXAtgZlQCIGuvOswEfA= -github.com/shirou/gopsutil/v4 v4.24.10 h1:7VOzPtfw/5YDU+jLEoBwXwxJbQetULywoSV4RYY7HkM= -github.com/shirou/gopsutil/v4 v4.24.10/go.mod h1:s4D/wg+ag4rG0WO7AiTj2BeYCRhym0vM7DHbZRxnIT8= +github.com/shirou/gopsutil/v4 v4.24.11 h1:WaU9xqGFKvFfsUv94SXcUPD7rCkU0vr/asVdQOBZNj8= +github.com/shirou/gopsutil/v4 v4.24.11/go.mod h1:s4D/wg+ag4rG0WO7AiTj2BeYCRhym0vM7DHbZRxnIT8= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= From 38deb28da5fc9aae01e3188b87c4afcb363655ad Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Mon, 16 Dec 2024 14:16:21 -0800 Subject: [PATCH 04/35] webview zoom (#1531) --- frontend/app/view/webview/webview.tsx | 92 ++++++++++++++++++++++++--- frontend/types/gotypes.d.ts | 1 + pkg/waveobj/metaconsts.go | 2 + pkg/waveobj/wtypemeta.go | 2 + 4 files changed, 88 insertions(+), 9 deletions(-) diff --git a/frontend/app/view/webview/webview.tsx b/frontend/app/view/webview/webview.tsx index 3cbcbe858..2ca31e8c4 100644 --- a/frontend/app/view/webview/webview.tsx +++ b/frontend/app/view/webview/webview.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { BlockNodeModel } from "@/app/block/blocktypes"; -import { getApi, getSettingsKeyAtom, openLink } from "@/app/store/global"; +import { getApi, getBlockMetaKeyAtom, getSettingsKeyAtom, openLink } from "@/app/store/global"; import { getSimpleControlShiftAtom } from "@/app/store/keymodel"; import { ObjectService } from "@/app/store/services"; import { RpcApi } from "@/app/store/wshclientapi"; @@ -49,13 +49,13 @@ export class WebViewModel implements ViewModel { mediaPlaying: PrimitiveAtom; mediaMuted: PrimitiveAtom; modifyExternalUrl?: (url: string) => string; + domReady: PrimitiveAtom; constructor(blockId: string, nodeModel: BlockNodeModel) { this.nodeModel = nodeModel; this.viewType = "web"; this.blockId = blockId; this.blockAtom = WOS.getWaveObjectAtom(`block:${blockId}`); - this.url = atom(); const defaultUrlAtom = getSettingsKeyAtom("web:defaulturl"); this.homepageUrl = atom((get) => { @@ -71,6 +71,7 @@ export class WebViewModel implements ViewModel { this.viewName = atom("Web"); this.urlInputRef = createRef(); this.webviewRef = createRef(); + this.domReady = atom(false); this.mediaPlaying = atom(false); this.mediaMuted = atom(false); @@ -339,7 +340,7 @@ export class WebViewModel implements ViewModel { const defaultSearchAtom = getSettingsKeyAtom("web:defaultsearch"); const searchTemplate = globalStore.get(defaultSearchAtom); const nextUrl = this.ensureUrlScheme(newUrl, searchTemplate); - console.log("webview loadUrl", reason, nextUrl, "cur=", this.webviewRef?.current.getURL()); + console.log("webview loadUrl", reason, nextUrl, "cur=", this.webviewRef.current.getURL()); if (!this.webviewRef.current) { return; } @@ -414,7 +415,7 @@ export class WebViewModel implements ViewModel { return true; } if (checkKeyPressed(e, "Cmd:r")) { - this.webviewRef?.current?.reload(); + this.webviewRef.current?.reload(); return true; } if (checkKeyPressed(e, "Cmd:ArrowLeft")) { @@ -428,7 +429,61 @@ export class WebViewModel implements ViewModel { return false; } + setZoomFactor(factor: number | null) { + // null is ok (will reset to default) + if (factor != null && factor < 0.1) { + factor = 0.1; + } + if (factor != null && factor > 5) { + factor = 5; + } + const domReady = globalStore.get(this.domReady); + if (!domReady) { + return; + } + this.webviewRef.current?.setZoomFactor(factor || 1); + RpcApi.SetMetaCommand(TabRpcClient, { + oref: WOS.makeORef("block", this.blockId), + meta: { "web:zoom": factor }, // allow null so we can remove the zoom factor here + }); + } + getSettingsMenuItems(): ContextMenuItem[] { + const zoomSubMenu: ContextMenuItem[] = []; + let curZoom = 1; + if (globalStore.get(this.domReady)) { + curZoom = this.webviewRef.current?.getZoomFactor() || 1; + } + const model = this; // for the closure to work (this is getting unset) + function makeZoomFactorMenuItem(label: string, factor: number): ContextMenuItem { + return { + label: label, + type: "checkbox", + click: () => { + model.setZoomFactor(factor); + }, + checked: curZoom == factor, + }; + } + zoomSubMenu.push({ + label: "Reset", + click: () => { + model.setZoomFactor(null); + }, + }); + zoomSubMenu.push(makeZoomFactorMenuItem("25%", 0.25)); + zoomSubMenu.push(makeZoomFactorMenuItem("50%", 0.5)); + zoomSubMenu.push(makeZoomFactorMenuItem("70%", 0.7)); + zoomSubMenu.push(makeZoomFactorMenuItem("80%", 0.8)); + zoomSubMenu.push(makeZoomFactorMenuItem("90%", 0.9)); + zoomSubMenu.push(makeZoomFactorMenuItem("100%", 1)); + zoomSubMenu.push(makeZoomFactorMenuItem("110%", 1.1)); + zoomSubMenu.push(makeZoomFactorMenuItem("120%", 1.2)); + zoomSubMenu.push(makeZoomFactorMenuItem("130%", 1.3)); + zoomSubMenu.push(makeZoomFactorMenuItem("150%", 1.5)); + zoomSubMenu.push(makeZoomFactorMenuItem("175%", 1.75)); + zoomSubMenu.push(makeZoomFactorMenuItem("200%", 2)); + return [ { label: "Set Block Homepage", @@ -441,6 +496,10 @@ export class WebViewModel implements ViewModel { { type: "separator", }, + { + label: "Set Zoom Factor", + submenu: zoomSubMenu, + }, { label: this.webviewRef.current?.isDevToolsOpened() ? "Close DevTools" : "Open DevTools", click: () => { @@ -476,12 +535,13 @@ const WebView = memo(({ model, onFailLoad }: WebViewProps) => { let metaUrl = blockData?.meta?.url || defaultUrl; metaUrl = model.ensureUrlScheme(metaUrl, defaultSearch); const metaUrlRef = useRef(metaUrl); + const zoomFactor = useAtomValue(getBlockMetaKeyAtom(model.blockId, "web:zoom")) || 1; // The initial value of the block metadata URL when the component first renders. Used to set the starting src value for the webview. const [metaUrlInitial] = useState(metaUrl); const [webContentsId, setWebContentsId] = useState(null); - const [domReady, setDomReady] = useState(false); + const domReady = useAtomValue(model.domReady); const [errorText, setErrorText] = useState(""); @@ -510,13 +570,27 @@ const WebView = memo(({ model, onFailLoad }: WebViewProps) => { } useEffect(() => { - if (model.webviewRef.current && domReady) { + return () => { + globalStore.set(model.domReady, false); + }; + }, []); + + useEffect(() => { + if (model.webviewRef.current == null || !domReady) { + return; + } + try { const wcId = model.webviewRef.current.getWebContentsId?.(); if (wcId) { setWebContentsId(wcId); + if (model.webviewRef.current.getZoomFactor() != zoomFactor) { + model.webviewRef.current.setZoomFactor(zoomFactor); + } } + } catch (e) { + console.error("Failed to get webcontentsid / setzoomlevel (webview)", e); } - }, [model.webviewRef.current, domReady]); + }, [model.webviewRef.current, domReady, zoomFactor]); // Load a new URL if the block metadata is updated. useEffect(() => { @@ -560,7 +634,7 @@ const WebView = memo(({ model, onFailLoad }: WebViewProps) => { console.error(errorMessage); setErrorText(errorMessage); if (onFailLoad) { - const curUrl = model.webviewRef?.current.getURL(); + const curUrl = model.webviewRef.current.getURL(); onFailLoad(curUrl); } } @@ -573,7 +647,7 @@ const WebView = memo(({ model, onFailLoad }: WebViewProps) => { getApi().setWebviewFocus(null); }; const handleDomReady = () => { - setDomReady(true); + globalStore.set(model.domReady, true); setBgColor(); }; const handleMediaPlaying = () => { diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 8584c1260..6f007767c 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -489,6 +489,7 @@ declare global { "term:scrollback"?: number; "term:vdomblockid"?: string; "term:vdomtoolbarblockid"?: string; + "web:zoom"?: number; "vdom:*"?: boolean; "vdom:initialized"?: boolean; "vdom:correlationid"?: string; diff --git a/pkg/waveobj/metaconsts.go b/pkg/waveobj/metaconsts.go index bc984fe9b..2d60bd497 100644 --- a/pkg/waveobj/metaconsts.go +++ b/pkg/waveobj/metaconsts.go @@ -94,6 +94,8 @@ const ( MetaKey_TermVDomSubBlockId = "term:vdomblockid" MetaKey_TermVDomToolbarBlockId = "term:vdomtoolbarblockid" + MetaKey_WebZoom = "web:zoom" + MetaKey_VDomClear = "vdom:*" MetaKey_VDomInitialized = "vdom:initialized" MetaKey_VDomCorrelationId = "vdom:correlationid" diff --git a/pkg/waveobj/wtypemeta.go b/pkg/waveobj/wtypemeta.go index 4aded7782..67ab6820c 100644 --- a/pkg/waveobj/wtypemeta.go +++ b/pkg/waveobj/wtypemeta.go @@ -95,6 +95,8 @@ type MetaTSType struct { TermVDomSubBlockId string `json:"term:vdomblockid,omitempty"` TermVDomToolbarBlockId string `json:"term:vdomtoolbarblockid,omitempty"` + WebZoom float64 `json:"web:zoom,omitempty"` + VDomClear bool `json:"vdom:*,omitempty"` VDomInitialized bool `json:"vdom:initialized,omitempty"` VDomCorrelationId string `json:"vdom:correlationid,omitempty"` From 99b5a08a2e03649591e01b0701b5701064986767 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:18:39 -0800 Subject: [PATCH 05/35] Bump electron from 33.2.0 to 33.2.1 in the electron group (#1513) Bumps the electron group with 1 update: [electron](https://github.com/electron/electron). Updates `electron` from 33.2.0 to 33.2.1
Release notes

Sourced from electron's releases.

electron v33.2.1

Release Notes for v33.2.1

Fixes

  • Fixed a crash that could occur when calling shell.readShortcutLink on Windows. #44803 (Also in 34)
  • Fixed an issue where WebContentsViews were being improperly removed. #44671 (Also in 31, 32, 34)
  • Fixed an issue where resize wasn't being emitted for single-pixel resizes on Windows. #44723 (Also in 32, 34)
  • Fixed an issue where a utilityProcess pid would not be undefined after exit. #44694 (Also in 32, 34)
  • Fixed an issue where buttons shown under the Window Controls Overlay API were missing tooltips. #44757 (Also in 32, 34)
  • Fixed an issue where the webContents context-menu event was not emitted when using -webkit-app-region: drag. #44800 (Also in 32, 34)
  • Fixed an issue where the windows control overlay was unexpectedly visible in fullscreen on Linux. #44640 (Also in 31, 32, 34)
  • Fixed crash in net api when utility process exits. #44729 (Also in 32, 34)
  • Fixed segfault when moving WebContentsView between BrowserWindows. #44613 (Also in 31, 32, 34)
  • Fixed theme does not work in DevTools. #44635 (Also in 32, 34)
  • Fixed update file extension bug. #44771 (Also in 34)
  • Return 0 exit code for normal termination of the utility process. #44732 (Also in 32, 34)

Other Changes

  • Fixed an issue where a deprecation warning was being incorrectly emitted for frameless windows on macOS. #44767 (Also in 34)
  • Fixed drag-and-drop session being canceled on wayland with empty dragData. #44753 (Also in 32)
  • Security: backported fix for CVE-2024-11110. #44647
  • Updated Chromium to 130.0.6723.137. #44781
  • Updated Node.js to v20.18.1. #44780
Commits
  • cd6e3d7 refactor: fix modernize-return-braced-init-list warnings (#44857)
  • 7152209 fix: modernize-use-using clang-tidy warnings (#44836)
  • 51e31de fix: modernize-use-nodiscard clang-tidy warnings (#44832)
  • fe3467e docs: correct stable release dates for v34.0.0 (#44830)
  • d0e24fc fix: clang-tidy performance-inefficient-vector-operation warnings (33-x-y) ...
  • 3483cd6 refactor: remove unnecessary constructor code (#44825)
  • 1ef8b47 fix: remove unused local variables (#44822)
  • 71c1149 docs: update new GitHub issue link (#44810)
  • bd5c8d7 fix: crash calling shell.readShortcutLink (#44803)
  • 52b5d8a fix: big endian bug in V8 serialization (#44796)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=electron&package-manager=npm_and_yarn&previous-version=33.2.0&new-version=33.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 3232e4a1b..c6941bec4 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@types/ws": "^8", "@vitejs/plugin-react-swc": "^3.7.2", "@vitest/coverage-istanbul": "^2.1.8", - "electron": "^33.2.0", + "electron": "^33.2.1", "electron-builder": "^25.1.8", "electron-vite": "^2.3.0", "eslint": "^9.16.0", diff --git a/yarn.lock b/yarn.lock index 6fe0eaa92..735e24a38 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10498,16 +10498,16 @@ __metadata: languageName: node linkType: hard -"electron@npm:^33.2.0": - version: 33.2.0 - resolution: "electron@npm:33.2.0" +"electron@npm:^33.2.1": + version: 33.3.0 + resolution: "electron@npm:33.3.0" dependencies: "@electron/get": "npm:^2.0.0" "@types/node": "npm:^20.9.0" extract-zip: "npm:^2.0.1" bin: electron: cli.js - checksum: 10c0/ad013bcc4fe65f6e0f40b77387452966347d4fb54acc8d8d7b0310244f73511a7ac87e03e1097970f83b94bcafc44e0b98a4c603daa9c95e11931d7c020ff155 + checksum: 10c0/ce381fb63da60b52b131aea473568aad2bff58cc3d8fd6fc68b4d0c0d5485e381e1a576727477ce901f4bd017baaa9e66f3f04da6ff698229343193258a8d38e languageName: node linkType: hard @@ -21986,7 +21986,7 @@ __metadata: css-tree: "npm:^3.0.1" dayjs: "npm:^1.11.13" debug: "npm:^4.3.7" - electron: "npm:^33.2.0" + electron: "npm:^33.2.1" electron-builder: "npm:^25.1.8" electron-updater: "npm:6.3.9" electron-vite: "npm:^2.3.0" From 51bd45bd2b663080a9a0d0eaa4ae9d932362edbe Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:24:32 -0800 Subject: [PATCH 06/35] Global Hotkey (#1534) Sets up a configurable global hotkey to focus the last window used in the application. Note that this is established at startup and configuration changes will not be applied until rebooting the app. --- emain/emain-util.ts | 21 +++++++++++++++++++++ emain/emain-window.ts | 24 ++++++++++++++++++++++-- emain/emain.ts | 5 +++++ frontend/types/gotypes.d.ts | 2 ++ pkg/wconfig/metaconsts.go | 3 +++ pkg/wconfig/settingsconfig.go | 3 +++ 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/emain/emain-util.ts b/emain/emain-util.ts index ffdffb370..16fbf9367 100644 --- a/emain/emain-util.ts +++ b/emain/emain-util.ts @@ -166,3 +166,24 @@ export function ensureBoundsAreVisible(bounds: electron.Rectangle): electron.Rec } return bounds; } + +export function waveKeyToElectronKey(waveKey: string): string { + const waveParts = waveKey.split(":"); + const electronParts: Array = waveParts.map((part: string) => { + if (part == "ArrowUp") { + return "Up"; + } + if (part == "ArrowDown") { + return "Down"; + } + if (part == "ArrowLeft") { + return "Left"; + } + if (part == "ArrowRight") { + return "Right"; + } + + return part; + }); + return electronParts.join("+"); +} diff --git a/emain/emain-window.ts b/emain/emain-window.ts index 9f3112616..7cc076ad5 100644 --- a/emain/emain-window.ts +++ b/emain/emain-window.ts @@ -3,7 +3,7 @@ import { ClientService, FileService, ObjectService, WindowService, WorkspaceService } from "@/app/store/services"; import { fireAndForget } from "@/util/util"; -import { BaseWindow, BaseWindowConstructorOptions, dialog, ipcMain, screen } from "electron"; +import { BaseWindow, BaseWindowConstructorOptions, dialog, globalShortcut, ipcMain, screen } from "electron"; import path from "path"; import { debounce } from "throttle-debounce"; import { @@ -14,7 +14,7 @@ import { setWasInFg, } from "./emain-activity"; import { getOrCreateWebViewForTab, getWaveTabViewByWebContentsId, WaveTabView } from "./emain-tabview"; -import { delay, ensureBoundsAreVisible } from "./emain-util"; +import { delay, ensureBoundsAreVisible, waveKeyToElectronKey } from "./emain-util"; import { log } from "./log"; import { getElectronAppBasePath, unamePlatform } from "./platform"; import { updater } from "./updater"; @@ -766,3 +766,23 @@ export async function relaunchBrowserWindows() { win.show(); } } + +export function registerGlobalHotkey(rawGlobalHotKey: string) { + try { + const electronHotKey = waveKeyToElectronKey(rawGlobalHotKey); + console.log("registering globalhotkey of ", electronHotKey); + globalShortcut.register(electronHotKey, () => { + const selectedWindow = focusedWaveWindow; + const firstWaveWindow = getAllWaveWindows()[0]; + if (focusedWaveWindow) { + selectedWindow.focus(); + } else if (firstWaveWindow) { + firstWaveWindow.focus(); + } else { + fireAndForget(createNewWaveWindow); + } + }); + } catch (e) { + console.log("error registering global hotkey: ", e); + } +} diff --git a/emain/emain.ts b/emain/emain.ts index 487f17c22..c5cf985be 100644 --- a/emain/emain.ts +++ b/emain/emain.ts @@ -38,6 +38,7 @@ import { getWaveWindowById, getWaveWindowByWebContentsId, getWaveWindowByWorkspaceId, + registerGlobalHotkey, relaunchBrowserWindows, WaveBrowserWindow, } from "./emain-window"; @@ -610,6 +611,10 @@ async function appMain() { fireAndForget(createNewWaveWindow); } }); + const rawGlobalHotKey = launchSettings?.["key:globalhotkey"]; + if (rawGlobalHotKey) { + registerGlobalHotkey(rawGlobalHotKey); + } } appMain().catch((e) => { diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 6f007767c..76b6c00fe 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -657,6 +657,8 @@ declare global { "window:magnifiedblocksize"?: number; "window:magnifiedblockblurprimarypx"?: number; "window:magnifiedblockblursecondarypx"?: number; + "key:*"?: boolean; + "key:globalhotkey"?: string; "telemetry:*"?: boolean; "telemetry:enabled"?: boolean; "conn:*"?: boolean; diff --git a/pkg/wconfig/metaconsts.go b/pkg/wconfig/metaconsts.go index 40c40f592..b01c8fdff 100644 --- a/pkg/wconfig/metaconsts.go +++ b/pkg/wconfig/metaconsts.go @@ -69,6 +69,9 @@ const ( ConfigKey_WindowMagnifiedBlockBlurPrimaryPx = "window:magnifiedblockblurprimarypx" ConfigKey_WindowMagnifiedBlockBlurSecondaryPx = "window:magnifiedblockblursecondarypx" + ConfigKey_KeyClear = "key:*" + ConfigKey_KeyGlobalHotkey = "key:globalhotkey" + ConfigKey_TelemetryClear = "telemetry:*" ConfigKey_TelemetryEnabled = "telemetry:enabled" diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index 5b64adae7..3992e5bda 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -96,6 +96,9 @@ type SettingsType struct { WindowMagnifiedBlockBlurPrimaryPx *int64 `json:"window:magnifiedblockblurprimarypx,omitempty"` WindowMagnifiedBlockBlurSecondaryPx *int64 `json:"window:magnifiedblockblursecondarypx,omitempty"` + KeyClear bool `json:"key:*,omitempty"` + KeyGlobalHotkey string `json:"key:globalhotkey,omitempty"` + TelemetryClear bool `json:"telemetry:*,omitempty"` TelemetryEnabled bool `json:"telemetry:enabled,omitempty"` From f1cd6b933d53af8381900ac523b8e78d7c792598 Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Mon, 16 Dec 2024 16:04:07 -0800 Subject: [PATCH 07/35] relative markdown text (#1489) --- .vscode/settings.json | 3 + frontend/app/element/markdown-util.ts | 59 ++++++++++++ frontend/app/element/markdown.scss | 134 ++++++++++++++------------ frontend/app/element/markdown.tsx | 94 ++++++++++++------ frontend/app/theme.scss | 6 +- frontend/app/view/preview/preview.tsx | 10 +- frontend/app/view/waveai/waveai.scss | 3 - frontend/app/view/waveai/waveai.tsx | 14 +-- frontend/types/gotypes.d.ts | 4 + package.json | 1 + pkg/waveobj/metaconsts.go | 3 + pkg/waveobj/wtypemeta.go | 3 + pkg/wconfig/metaconsts.go | 3 + pkg/wconfig/settingsconfig.go | 3 + yarn.lock | 8 ++ 15 files changed, 246 insertions(+), 102 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index d0b01c951..831ce237f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,9 @@ "[less]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[scss]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, diff --git a/frontend/app/element/markdown-util.ts b/frontend/app/element/markdown-util.ts index 0892d8453..9bb6d8781 100644 --- a/frontend/app/element/markdown-util.ts +++ b/frontend/app/element/markdown-util.ts @@ -1,6 +1,12 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 +import { RpcApi } from "@/app/store/wshclientapi"; +import { TabRpcClient } from "@/app/store/wshrpcutil"; +import { getWebServerEndpoint } from "@/util/endpoints"; +import { isBlank, makeConnRoute } from "@/util/util"; +import parseSrcSet from "parse-srcset"; + export type MarkdownContentBlockType = { type: string; id: string; @@ -147,3 +153,56 @@ export function transformBlocks(content: string): { content: string; blocks: Map blocks: blocks, }; } + +export const resolveRemoteFile = async (filepath: string, resolveOpts: MarkdownResolveOpts): Promise => { + if (!filepath || filepath.startsWith("http://") || filepath.startsWith("https://")) { + return filepath; + } + + try { + const route = makeConnRoute(resolveOpts.connName); + const fileInfo = await RpcApi.RemoteFileJoinCommand(TabRpcClient, [resolveOpts.baseDir, filepath], { + route: route, + }); + + const usp = new URLSearchParams(); + usp.set("path", fileInfo.path); + if (!isBlank(resolveOpts.connName)) { + usp.set("connection", resolveOpts.connName); + } + + return getWebServerEndpoint() + "/wave/stream-file?" + usp.toString(); + } catch (err) { + console.warn("Failed to resolve remote file:", filepath, err); + return null; + } +}; + +export const resolveSrcSet = async (srcSet: string, resolveOpts: MarkdownResolveOpts): Promise => { + if (!srcSet) return null; + + // Parse the srcset + const candidates = parseSrcSet(srcSet); + + // Resolve each URL in the array of candidates + const resolvedCandidates = await Promise.all( + candidates.map(async (candidate) => { + const resolvedUrl = await resolveRemoteFile(candidate.url, resolveOpts); + return { + ...candidate, + url: resolvedUrl, + }; + }) + ); + + // Reconstruct the srcset string + return resolvedCandidates + .map((candidate) => { + let part = candidate.url; + if (candidate.w) part += ` ${candidate.w}w`; + if (candidate.h) part += ` ${candidate.h}h`; + if (candidate.d) part += ` ${candidate.d}x`; + return part; + }) + .join(", "); +}; diff --git a/frontend/app/element/markdown.scss b/frontend/app/element/markdown.scss index b485806d3..4bee56855 100644 --- a/frontend/app/element/markdown.scss +++ b/frontend/app/element/markdown.scss @@ -16,21 +16,66 @@ overflow: scroll; line-height: 1.5; color: var(--main-text-color); - font-family: var(--markdown-font); - font-size: 14px; + font-family: var(--markdown-font-family); + font-size: var(--markdown-font-size); overflow-wrap: break-word; &.non-scrollable { overflow: hidden; } + .heading:not(.heading ~ .heading) { + margin-top: 0 !important; + } + .heading { - &:first-of-type { - margin-top: 0 !important; - } color: var(--main-text-color); - margin-top: 16px; - margin-bottom: 8px; + margin-top: 1.143em; + margin-bottom: 0.571em; + font-weight: semibold; + padding-top: 0.429em; + + &.is-1 { + border-bottom: 1px solid var(--border-color); + padding-bottom: 0.429em; + font-size: 2em; + } + &.is-2 { + border-bottom: 1px solid var(--border-color); + padding-bottom: 0.429em; + font-size: 1.5em; + } + &.is-3 { + font-size: 1.25em; + } + &.is-4 { + font-size: 1em; + } + &.is-5 { + font-size: 0.875em; + } + &.is-6 { + font-size: 0.85em; + } + } + + .paragraph { + margin-top: 0; + margin-bottom: 10px; + } + + img { + border-style: none; + max-width: 100%; + box-sizing: content-box; + + &[align="right"] { + padding-left: 20px; + } + + &[align="left"] { + padding-right: 20px; + } } strong { @@ -44,24 +89,24 @@ ul { list-style-type: disc; list-style-position: outside; - margin-left: 16px; + margin-left: 1.143em; } ol { list-style-position: outside; - margin-left: 19px; + margin-left: 1.357em; } blockquote { - margin: 4px 10px 4px 10px; - border-radius: 3px; + margin: 0.286em 0.714em; + border-radius: 4px; background-color: var(--panel-bg-color); - padding: 2px 4px 2px 6px; + padding: 0.143em 0.286em 0.143em 0.429em; } pre.codeblock { background-color: var(--panel-bg-color); - margin: 4px 10px; + margin: 0.286em 0.714em; padding: 0.4em 0.7em; border-radius: 4px; position: relative; @@ -83,11 +128,11 @@ right: 0; border-radius: 4px; backdrop-filter: blur(8px); - margin: 2px 2px; - padding: 4px 4px; + margin: 0.143em; + padding: 0.286em; align-items: center; justify-content: flex-end; - gap: 4px; + gap: 0.286em; } &:hover .codeblock-actions { @@ -98,6 +143,7 @@ code { color: var(--main-text-color); font: var(--fixed-font); + font-size: var(--markdown-fixed-font-size); border-radius: 4px; } @@ -105,41 +151,13 @@ outline: 2px solid var(--accent-color); } - .heading { - font-weight: semibold; - padding-top: 6px; - } - - .heading.is-1 { - border-bottom: 1px solid var(--border-color); - padding-bottom: 6px; - font-size: 2em; - } - .heading.is-2 { - border-bottom: 1px solid var(--border-color); - padding-bottom: 6px; - font-size: 1.5em; - } - .heading.is-3 { - font-size: 1.25em; - } - .heading.is-4 { - font-size: 1em; - } - .heading.is-5 { - font-size: 0.875em; - } - .heading.is-6 { - font-size: 0.85em; - } - .waveblock { - margin: 16px 0; + margin: 1.143em 0; .wave-block-content { display: flex; align-items: center; - padding: 12px; + padding: 0.857em; background-color: var(--highlight-bg-color); border: 1px solid var(--border-color); border-radius: 8px; @@ -150,15 +168,15 @@ display: flex; align-items: center; justify-content: center; - width: 40px; - height: 40px; + width: 2.857em; + height: 2.857em; background-color: black; border-radius: 8px; - margin-right: 12px; + margin-right: 0.857em; } .wave-block-icon i { - font-size: 18px; + font-size: 1.125em; color: var(--secondary-text-color); } @@ -168,19 +186,18 @@ } .wave-block-filename { - font-size: 14px; + font-size: 1em; font-weight: 500; color: var(--main-text-color); } .wave-block-size { - font-size: 12px; + font-size: 0.857em; color: var(--secondary-text-color); } } } - // The TOC view should scroll independently of the contents view. .toc { max-width: 40%; height: 100%; @@ -192,21 +209,20 @@ top: 0; display: flex; flex-direction: column; - gap: 5px; + gap: 0.357em; text-wrap: wrap; h4 { - padding-left: 5px; + padding-left: 0.357em; } .toc-item { cursor: pointer; --indent-factor: 1; - - // The 5px offset in the padding will ensure that when the text in the item wraps, it indents slightly. + // The offset in the padding will ensure that when the text in the item wraps, it indents slightly. // The indent factor is set in the React code and denotes the depth of the item in the TOC tree. - padding-left: calc((var(--indent-factor) - 1) * 10px + 5px); - text-indent: -5px; + padding-left: calc((var(--indent-factor) - 1) * 0.714em + 0.357em); + text-indent: -0.357em; } } } diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx index c6e58fb63..5e6f596cf 100644 --- a/frontend/app/element/markdown.tsx +++ b/frontend/app/element/markdown.tsx @@ -3,11 +3,13 @@ import { CopyButton } from "@/app/element/copybutton"; import { createContentBlockPlugin } from "@/app/element/markdown-contentblock-plugin"; -import { MarkdownContentBlockType, transformBlocks } from "@/app/element/markdown-util"; -import { RpcApi } from "@/app/store/wshclientapi"; -import { TabRpcClient } from "@/app/store/wshrpcutil"; -import { getWebServerEndpoint } from "@/util/endpoints"; -import { isBlank, makeConnRoute, useAtomValueSafe } from "@/util/util"; +import { + MarkdownContentBlockType, + resolveRemoteFile, + resolveSrcSet, + transformBlocks, +} from "@/app/element/markdown-util"; +import { useAtomValueSafe } from "@/util/util"; import { clsx } from "clsx"; import { Atom } from "jotai"; import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react"; @@ -108,8 +110,34 @@ const CodeBlock = ({ children, onClickExecute }: CodeBlockProps) => { ); }; -const MarkdownSource = (props: React.HTMLAttributes) => { - return null; +const MarkdownSource = ({ + props, + resolveOpts, +}: { + props: React.HTMLAttributes & { + srcSet?: string; + media?: string; + }; + resolveOpts: MarkdownResolveOpts; +}) => { + const [resolvedSrcSet, setResolvedSrcSet] = useState(props.srcSet); + const [resolving, setResolving] = useState(true); + + useEffect(() => { + const resolvePath = async () => { + const resolved = await resolveSrcSet(props.srcSet, resolveOpts); + setResolvedSrcSet(resolved); + setResolving(false); + }; + + resolvePath(); + }, [props.srcSet]); + + if (resolving) { + return null; + } + + return ; }; interface WaveBlockProps { @@ -148,16 +176,11 @@ const MarkdownImg = ({ resolveOpts: MarkdownResolveOpts; }) => { const [resolvedSrc, setResolvedSrc] = useState(props.src); + const [resolvedSrcSet, setResolvedSrcSet] = useState(props.srcSet); const [resolvedStr, setResolvedStr] = useState(null); const [resolving, setResolving] = useState(true); useEffect(() => { - if (props.src.startsWith("http://") || props.src.startsWith("https://")) { - setResolving(false); - setResolvedSrc(props.src); - setResolvedStr(null); - return; - } if (props.src.startsWith("data:image/")) { setResolving(false); setResolvedSrc(props.src); @@ -170,23 +193,20 @@ const MarkdownImg = ({ setResolvedStr(`[img:${props.src}]`); return; } + const resolveFn = async () => { - const route = makeConnRoute(resolveOpts.connName); - const fileInfo = await RpcApi.RemoteFileJoinCommand(TabRpcClient, [resolveOpts.baseDir, props.src], { - route: route, - }); - const usp = new URLSearchParams(); - usp.set("path", fileInfo.path); - if (!isBlank(resolveOpts.connName)) { - usp.set("connection", resolveOpts.connName); - } - const streamingUrl = getWebServerEndpoint() + "/wave/stream-file?" + usp.toString(); - setResolvedSrc(streamingUrl); + const [resolvedSrc, resolvedSrcSet] = await Promise.all([ + resolveRemoteFile(props.src, resolveOpts), + resolveSrcSet(props.srcSet, resolveOpts), + ]); + + setResolvedSrc(resolvedSrc); + setResolvedSrcSet(resolvedSrcSet); setResolvedStr(null); setResolving(false); }; resolveFn(); - }, [props.src]); + }, [props.src, props.srcSet]); if (resolving) { return null; @@ -195,7 +215,7 @@ const MarkdownImg = ({ return {resolvedStr}; } if (resolvedSrc != null) { - return ; + return ; } return [img]; }; @@ -210,6 +230,8 @@ type MarkdownProps = { resolveOpts?: MarkdownResolveOpts; scrollable?: boolean; rehype?: boolean; + fontSizeOverride?: number; + fixedFontSizeOverride?: number; }; const Markdown = ({ @@ -219,6 +241,8 @@ const Markdown = ({ style, className, resolveOpts, + fontSizeOverride, + fixedFontSizeOverride, scrollable = true, rehype = true, onClickExecute, @@ -262,7 +286,9 @@ const Markdown = ({ h5: (props: React.HTMLAttributes) => , h6: (props: React.HTMLAttributes) => , img: (props: React.HTMLAttributes) => , - source: (props: React.HTMLAttributes) => , + source: (props: React.HTMLAttributes) => ( + + ), code: Code, pre: (props: React.HTMLAttributes) => ( @@ -301,12 +327,15 @@ const Markdown = ({ ...(defaultSchema.attributes?.span || []), // Allow all class names starting with `hljs-`. ["className", /^hljs-./], + ["srcset"], + ["media"], + ["type"], // Alternatively, to allow only certain class names: // ['className', 'hljs-number', 'hljs-title', 'hljs-variable'] ], waveblock: [["blockkey"]], }, - tagNames: [...(defaultSchema.tagNames || []), "span", "waveblock"], + tagNames: [...(defaultSchema.tagNames || []), "span", "waveblock", "picture", "source"], }), () => rehypeSlug({ prefix: idPrefix }), ]; @@ -349,8 +378,15 @@ const Markdown = ({ ); }; + const mergedStyle = { ...style }; + if (fontSizeOverride != null) { + mergedStyle["--markdown-font-size"] = `${fontSizeOverride}px`; + } + if (fixedFontSizeOverride != null) { + mergedStyle["--markdown-fixed-font-size"] = `${fixedFontSizeOverride}px`; + } return ( -
+
{scrollable ? : } {toc && ( diff --git a/frontend/app/theme.scss b/frontend/app/theme.scss index ad9931a4b..9f25430c4 100644 --- a/frontend/app/theme.scss +++ b/frontend/app/theme.scss @@ -1,8 +1,6 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -// Used for syntax highlighting in markdown - :root { --main-text-color: #f7f7f7; --title-font-size: 18px; @@ -16,8 +14,10 @@ --accent-color: rgb(88, 193, 66); --panel-bg-color: rgba(31, 33, 31, 0.5); --highlight-bg-color: rgba(255, 255, 255, 0.2); - --markdown-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, + --markdown-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + --markdown-font-size: 14px; + --markdown-fixed-font-size: 12px; --error-color: rgb(229, 77, 46); --warning-color: rgb(224, 185, 86); --success-color: rgb(78, 154, 6); diff --git a/frontend/app/view/preview/preview.tsx b/frontend/app/view/preview/preview.tsx index 3a5c1e1bd..0c89d9428 100644 --- a/frontend/app/view/preview/preview.tsx +++ b/frontend/app/view/preview/preview.tsx @@ -783,6 +783,8 @@ function makePreviewModel(blockId: string, nodeModel: BlockNodeModel): PreviewMo function MarkdownPreview({ model }: SpecializedViewProps) { const connName = useAtomValue(model.connection); const fileInfo = useAtomValue(model.statFile); + const fontSizeOverride = useAtomValue(getOverrideConfigAtom(model.blockId, "markdown:fontsize")); + const fixedFontSizeOverride = useAtomValue(getOverrideConfigAtom(model.blockId, "markdown:fixedfontsize")); const resolveOpts: MarkdownResolveOpts = useMemo(() => { return { connName: connName, @@ -791,7 +793,13 @@ function MarkdownPreview({ model }: SpecializedViewProps) { }, [connName, fileInfo.dir]); return (
- +
); } diff --git a/frontend/app/view/waveai/waveai.scss b/frontend/app/view/waveai/waveai.scss index c35a5e24e..4a2020e5c 100644 --- a/frontend/app/view/waveai/waveai.scss +++ b/frontend/app/view/waveai/waveai.scss @@ -131,9 +131,6 @@ outline: none; overflow: auto; overflow-wrap: anywhere; - font-family: var(--termfontfamily); - font-weight: normal; - line-height: var(--termlineheight); height: 21px; } } diff --git a/frontend/app/view/waveai/waveai.tsx b/frontend/app/view/waveai/waveai.tsx index 6c0c02a38..b84bdd37f 100644 --- a/frontend/app/view/waveai/waveai.tsx +++ b/frontend/app/view/waveai/waveai.tsx @@ -569,7 +569,7 @@ const ChatWindow = memo( interface ChatInputProps { value: string; - termFontSize: number; + baseFontSize: number; onChange: (e: React.ChangeEvent) => void; onKeyDown: (e: React.KeyboardEvent) => void; onMouseDown: (e: React.MouseEvent) => void; @@ -577,7 +577,7 @@ interface ChatInputProps { } const ChatInput = forwardRef( - ({ value, onChange, onKeyDown, onMouseDown, termFontSize, model }, ref) => { + ({ value, onChange, onKeyDown, onMouseDown, baseFontSize, model }, ref) => { const textAreaRef = useRef(null); useImperativeHandle(ref, () => textAreaRef.current as HTMLTextAreaElement); @@ -594,7 +594,7 @@ const ChatInput = forwardRef( // Adjust the height of the textarea to fit the text const textAreaMaxLines = 5; - const textAreaLineHeight = termFontSize * 1.5; + const textAreaLineHeight = baseFontSize * 1.5; const textAreaMinHeight = textAreaLineHeight; const textAreaMaxHeight = textAreaLineHeight * textAreaMaxLines; @@ -608,7 +608,7 @@ const ChatInput = forwardRef( const newHeight = Math.min(Math.max(scrollHeight, textAreaMinHeight), textAreaMaxHeight); textAreaRef.current.style.height = newHeight + "px"; }, - [termFontSize] + [baseFontSize] ); useEffect(() => { @@ -624,7 +624,7 @@ const ChatInput = forwardRef( onMouseDown={onMouseDown} // When the user clicks on the textarea onChange={onChange} onKeyDown={onKeyDown} - style={{ fontSize: termFontSize }} + style={{ fontSize: baseFontSize }} placeholder="Ask anything..." value={value} > @@ -642,7 +642,7 @@ const WaveAi = ({ model }: { model: WaveAiModel; blockId: string }) => { const [value, setValue] = useState(""); const [selectedBlockIdx, setSelectedBlockIdx] = useState(null); - const termFontSize: number = 14; + const baseFontSize: number = 14; const msgWidths = {}; const locked = useAtomValue(model.locked); @@ -815,7 +815,7 @@ const WaveAi = ({ model }: { model: WaveAiModel; blockId: string }) => { onChange={handleTextAreaChange} onKeyDown={handleTextAreaKeyDown} onMouseDown={handleTextAreaMouseDown} - termFontSize={termFontSize} + baseFontSize={baseFontSize} />
- +
); @@ -459,7 +466,12 @@ const ChatItem = ({ chatItem }: ChatItemProps) => {
- +
) : ( @@ -474,11 +486,17 @@ const ChatItem = ({ chatItem }: ChatItemProps) => { return ( <>
- +
); - }, [text, user]); + }, [text, user, fontSize, fixedFontSize]); return
{renderContent}
; }; @@ -487,10 +505,11 @@ interface ChatWindowProps { chatWindowRef: React.RefObject; messages: ChatMessageType[]; msgWidths: Object; + model: WaveAiModel; } const ChatWindow = memo( - forwardRef(({ chatWindowRef, messages, msgWidths }, ref) => { + forwardRef(({ chatWindowRef, messages, msgWidths, model }, ref) => { const [isUserScrolling, setIsUserScrolling] = useState(false); const osRef = useRef(null); @@ -559,7 +578,7 @@ const ChatWindow = memo(
{messages.map((chitem, idx) => ( - + ))}
@@ -804,7 +823,13 @@ const WaveAi = ({ model }: { model: WaveAiModel; blockId: string }) => { return (
- +
diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index afd3e6d24..afd817690 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -617,6 +617,8 @@ declare global { "ai:apiversion"?: string; "ai:maxtokens"?: number; "ai:timeoutms"?: number; + "ai:fontsize"?: number; + "ai:fixedfontsize"?: number; "term:*"?: boolean; "term:fontsize"?: number; "term:fontfamily"?: string; @@ -629,6 +631,7 @@ declare global { "editor:minimapenabled"?: boolean; "editor:stickyscrollenabled"?: boolean; "editor:wordwrap"?: boolean; + "editor:fontsize"?: number; "web:*"?: boolean; "web:openlinksinternally"?: boolean; "web:defaulturl"?: string; diff --git a/pkg/wconfig/metaconsts.go b/pkg/wconfig/metaconsts.go index 42c7c89bd..6e62b5c20 100644 --- a/pkg/wconfig/metaconsts.go +++ b/pkg/wconfig/metaconsts.go @@ -17,6 +17,8 @@ const ( ConfigKey_AIApiVersion = "ai:apiversion" ConfigKey_AiMaxTokens = "ai:maxtokens" ConfigKey_AiTimeoutMs = "ai:timeoutms" + ConfigKey_AiFontSize = "ai:fontsize" + ConfigKey_AiFixedFontSize = "ai:fixedfontsize" ConfigKey_TermClear = "term:*" ConfigKey_TermFontSize = "term:fontsize" @@ -31,6 +33,7 @@ const ( ConfigKey_EditorMinimapEnabled = "editor:minimapenabled" ConfigKey_EditorStickyScrollEnabled = "editor:stickyscrollenabled" ConfigKey_EditorWordWrap = "editor:wordwrap" + ConfigKey_EditorFontSize = "editor:fontsize" ConfigKey_WebClear = "web:*" ConfigKey_WebOpenLinksInternally = "web:openlinksinternally" diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index dc2671e4a..6b9e58319 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -33,17 +33,19 @@ const AnySchema = ` ` type SettingsType struct { - AiClear bool `json:"ai:*,omitempty"` - AiPreset string `json:"ai:preset,omitempty"` - AiApiType string `json:"ai:apitype,omitempty"` - AiBaseURL string `json:"ai:baseurl,omitempty"` - AiApiToken string `json:"ai:apitoken,omitempty"` - AiName string `json:"ai:name,omitempty"` - AiModel string `json:"ai:model,omitempty"` - AiOrgID string `json:"ai:orgid,omitempty"` - AIApiVersion string `json:"ai:apiversion,omitempty"` - AiMaxTokens float64 `json:"ai:maxtokens,omitempty"` - AiTimeoutMs float64 `json:"ai:timeoutms,omitempty"` + AiClear bool `json:"ai:*,omitempty"` + AiPreset string `json:"ai:preset,omitempty"` + AiApiType string `json:"ai:apitype,omitempty"` + AiBaseURL string `json:"ai:baseurl,omitempty"` + AiApiToken string `json:"ai:apitoken,omitempty"` + AiName string `json:"ai:name,omitempty"` + AiModel string `json:"ai:model,omitempty"` + AiOrgID string `json:"ai:orgid,omitempty"` + AIApiVersion string `json:"ai:apiversion,omitempty"` + AiMaxTokens float64 `json:"ai:maxtokens,omitempty"` + AiTimeoutMs float64 `json:"ai:timeoutms,omitempty"` + AiFontSize float64 `json:"ai:fontsize,omitempty"` + AiFixedFontSize float64 `json:"ai:fixedfontsize,omitempty"` TermClear bool `json:"term:*,omitempty"` TermFontSize float64 `json:"term:fontsize,omitempty"` @@ -55,9 +57,10 @@ type SettingsType struct { TermScrollback *int64 `json:"term:scrollback,omitempty"` TermCopyOnSelect *bool `json:"term:copyonselect,omitempty"` - EditorMinimapEnabled bool `json:"editor:minimapenabled,omitempty"` - EditorStickyScrollEnabled bool `json:"editor:stickyscrollenabled,omitempty"` - EditorWordWrap bool `json:"editor:wordwrap,omitempty"` + EditorMinimapEnabled bool `json:"editor:minimapenabled,omitempty"` + EditorStickyScrollEnabled bool `json:"editor:stickyscrollenabled,omitempty"` + EditorWordWrap bool `json:"editor:wordwrap,omitempty"` + EditorFontSize float64 `json:"editor:fontsize,omitempty"` WebClear bool `json:"web:*,omitempty"` WebOpenLinksInternally bool `json:"web:openlinksinternally,omitempty"` From 1ba370e4dd316a6aa6096b17b03ea9c2cb960106 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Mon, 16 Dec 2024 18:31:01 -0800 Subject: [PATCH 11/35] Fix iconbutton styling (#1538) --- frontend/app/block/block.scss | 4 ++-- frontend/app/tab/workspaceswitcher.scss | 6 +++--- frontend/app/view/webview/webview.scss | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/app/block/block.scss b/frontend/app/block/block.scss index 58a69c26e..87c5c645b 100644 --- a/frontend/app/block/block.scss +++ b/frontend/app/block/block.scss @@ -236,7 +236,7 @@ display: flex; flex-shrink: 0; - .iconbutton { + .wave-iconbutton { display: flex; width: 24px; padding: 4px 6px; @@ -268,7 +268,7 @@ align-items: center; justify-content: center; - .iconbutton { + .wave-iconbutton { opacity: 0.7; font-size: 45px; margin: -30px 0 0 0; diff --git a/frontend/app/tab/workspaceswitcher.scss b/frontend/app/tab/workspaceswitcher.scss index a1b5545b8..596622501 100644 --- a/frontend/app/tab/workspaceswitcher.scss +++ b/frontend/app/tab/workspaceswitcher.scss @@ -100,17 +100,17 @@ gap: 5px; } - .iconbutton.edit { + .wave-iconbutton.edit { visibility: hidden; } - .iconbutton.window { + .wave-iconbutton.window { cursor: default; opacity: 1 !important; } } - &:hover .iconbutton.edit { + &:hover .wave-iconbutton.edit { visibility: visible; } diff --git a/frontend/app/view/webview/webview.scss b/frontend/app/view/webview/webview.scss index 761e556ba..960e5fa3b 100644 --- a/frontend/app/view/webview/webview.scss +++ b/frontend/app/view/webview/webview.scss @@ -42,7 +42,7 @@ opacity: 1; } - .iconbutton { + .wave-iconbutton { width: fit-content !important; margin-right: 5px; } From 78f3cd04722eff61986b1c4011c9da06f87acc48 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Mon, 16 Dec 2024 21:54:13 -0800 Subject: [PATCH 12/35] Synchronize workspace edits across windows, close window when workspace is deleted (#1540) --- frontend/app/tab/workspaceeditor.scss | 70 ++++++++ frontend/app/tab/workspaceeditor.tsx | 125 +++++++++++++++ frontend/app/tab/workspaceswitcher.scss | 115 +++----------- frontend/app/tab/workspaceswitcher.tsx | 149 +++--------------- .../workspaceservice/workspaceservice.go | 3 + pkg/wcore/window.go | 19 +-- pkg/wcore/workspace.go | 7 + 7 files changed, 256 insertions(+), 232 deletions(-) create mode 100644 frontend/app/tab/workspaceeditor.scss create mode 100644 frontend/app/tab/workspaceeditor.tsx diff --git a/frontend/app/tab/workspaceeditor.scss b/frontend/app/tab/workspaceeditor.scss new file mode 100644 index 000000000..d850d0a94 --- /dev/null +++ b/frontend/app/tab/workspaceeditor.scss @@ -0,0 +1,70 @@ +.workspace-editor { + width: 100%; + .input { + margin: 5px 0 10px; + } + + .color-selector { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(15px, 15px)); // Ensures each color circle has a fixed 14px size + grid-gap: 18.5px; // Space between items + justify-content: center; + align-items: center; + margin-top: 5px; + padding-bottom: 15px; + border-bottom: 1px solid var(--modal-border-color); + + .color-circle { + width: 15px; + height: 15px; + border-radius: 50%; + cursor: pointer; + position: relative; + + // Border offset outward + &:before { + content: ""; + position: absolute; + top: -3px; + left: -3px; + right: -3px; + bottom: -3px; + border-radius: 50%; + border: 1px solid transparent; + } + + &.selected:before { + border-color: var(--main-text-color); // Highlight for the selected circle + } + } + } + + .icon-selector { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(16px, 16px)); // Ensures each color circle has a fixed 14px size + grid-column-gap: 17.5px; // Space between items + grid-row-gap: 13px; // Space between items + justify-content: center; + align-items: center; + margin-top: 15px; + + .icon-item { + font-size: 15px; + color: oklch(from var(--modal-bg-color) calc(l * 1.5) c h); + cursor: pointer; + transition: color 0.3s ease; + + &.selected, + &:hover { + color: var(--main-text-color); + } + } + } + + .delete-ws-btn-wrapper { + display: flex; + align-items: center; + justify-content: center; + margin-top: 10px; + } +} diff --git a/frontend/app/tab/workspaceeditor.tsx b/frontend/app/tab/workspaceeditor.tsx new file mode 100644 index 000000000..e2fde28e9 --- /dev/null +++ b/frontend/app/tab/workspaceeditor.tsx @@ -0,0 +1,125 @@ +import { fireAndForget, makeIconClass } from "@/util/util"; +import clsx from "clsx"; +import { memo, useEffect, useRef, useState } from "react"; +import { Button } from "../element/button"; +import { Input } from "../element/input"; +import { WorkspaceService } from "../store/services"; +import "./workspaceeditor.scss"; + +interface ColorSelectorProps { + colors: string[]; + selectedColor?: string; + onSelect: (color: string) => void; + className?: string; +} + +const ColorSelector = memo(({ colors, selectedColor, onSelect, className }: ColorSelectorProps) => { + const handleColorClick = (color: string) => { + onSelect(color); + }; + + return ( +
+ {colors.map((color) => ( +
handleColorClick(color)} + /> + ))} +
+ ); +}); + +interface IconSelectorProps { + icons: string[]; + selectedIcon?: string; + onSelect: (icon: string) => void; + className?: string; +} + +const IconSelector = memo(({ icons, selectedIcon, onSelect, className }: IconSelectorProps) => { + const handleIconClick = (icon: string) => { + onSelect(icon); + }; + + return ( +
+ {icons.map((icon) => { + const iconClass = makeIconClass(icon, true); + return ( + handleIconClick(icon)} + /> + ); + })} +
+ ); +}); + +interface WorkspaceEditorProps { + title: string; + icon: string; + color: string; + focusInput: boolean; + onTitleChange: (newTitle: string) => void; + onColorChange: (newColor: string) => void; + onIconChange: (newIcon: string) => void; + onDeleteWorkspace: () => void; +} +const WorkspaceEditorComponent = ({ + title, + icon, + color, + focusInput, + onTitleChange, + onColorChange, + onIconChange, + onDeleteWorkspace, +}: WorkspaceEditorProps) => { + const inputRef = useRef(null); + + const [colors, setColors] = useState([]); + const [icons, setIcons] = useState([]); + + useEffect(() => { + fireAndForget(async () => { + const colors = await WorkspaceService.GetColors(); + const icons = await WorkspaceService.GetIcons(); + setColors(colors); + setIcons(icons); + }); + }, []); + + useEffect(() => { + if (focusInput && inputRef.current) { + inputRef.current.focus(); + inputRef.current.select(); + } + }, [focusInput]); + + return ( +
+ + + +
+ +
+
+ ); +}; + +export const WorkspaceEditor = memo(WorkspaceEditorComponent) as typeof WorkspaceEditorComponent; diff --git a/frontend/app/tab/workspaceswitcher.scss b/frontend/app/tab/workspaceswitcher.scss index 596622501..c8b3e1fa9 100644 --- a/frontend/app/tab/workspaceswitcher.scss +++ b/frontend/app/tab/workspaceswitcher.scss @@ -26,25 +26,6 @@ } } -.icon-left, -.icon-right { - display: flex; - align-items: center; - justify-content: center; - font-size: 20px; -} - -.divider { - width: 1px; - height: 20px; - background: rgba(255, 255, 255, 0.08); -} - -.scrollable { - max-height: 400px; - width: 100%; -} - .workspace-switcher-content { min-height: auto; display: flex; @@ -55,6 +36,25 @@ border-radius: 8px; box-shadow: 0px 8px 24px 0px var(--modal-shadow-color); + .icon-left, + .icon-right { + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + } + + .divider { + width: 1px; + height: 20px; + background: rgba(255, 255, 255, 0.08); + } + + .scrollable { + max-height: 400px; + width: 100%; + } + .title { font-size: 12px; line-height: 19px; @@ -144,83 +144,6 @@ padding: 0; } - .workspace-editor { - width: 100%; - .input { - margin: 5px 0 10px; - } - - .color-selector { - display: grid; - grid-template-columns: repeat( - auto-fit, - minmax(15px, 15px) - ); // Ensures each color circle has a fixed 14px size - grid-gap: 18.5px; // Space between items - justify-content: center; - align-items: center; - margin-top: 5px; - padding-bottom: 15px; - border-bottom: 1px solid var(--modal-border-color); - - .color-circle { - width: 15px; - height: 15px; - border-radius: 50%; - cursor: pointer; - position: relative; - - // Border offset outward - &:before { - content: ""; - position: absolute; - top: -3px; - left: -3px; - right: -3px; - bottom: -3px; - border-radius: 50%; - border: 1px solid transparent; - } - - &.selected:before { - border-color: var(--main-text-color); // Highlight for the selected circle - } - } - } - - .icon-selector { - display: grid; - grid-template-columns: repeat( - auto-fit, - minmax(16px, 16px) - ); // Ensures each color circle has a fixed 14px size - grid-column-gap: 17.5px; // Space between items - grid-row-gap: 13px; // Space between items - justify-content: center; - align-items: center; - margin-top: 15px; - - .icon-item { - font-size: 15px; - color: oklch(from var(--modal-bg-color) calc(l * 1.5) c h); - cursor: pointer; - transition: color 0.3s ease; - - &.selected, - &:hover { - color: var(--main-text-color); - } - } - } - - .delete-ws-btn-wrapper { - display: flex; - align-items: center; - justify-content: center; - margin-top: 10px; - } - } - .actions { width: 100%; padding: 3px 0; diff --git a/frontend/app/tab/workspaceswitcher.tsx b/frontend/app/tab/workspaceswitcher.tsx index 9f204b2ae..bd995a611 100644 --- a/frontend/app/tab/workspaceswitcher.tsx +++ b/frontend/app/tab/workspaceswitcher.tsx @@ -1,7 +1,6 @@ // Copyright 2024, Command Line // SPDX-License-Identifier: Apache-2.0 -import { Button } from "@/element/button"; import { ExpandableMenu, ExpandableMenuItem, @@ -10,139 +9,22 @@ import { ExpandableMenuItemLeftElement, ExpandableMenuItemRightElement, } from "@/element/expandablemenu"; -import { Input } from "@/element/input"; import { Popover, PopoverButton, PopoverContent } from "@/element/popover"; import { fireAndForget, makeIconClass, useAtomValueSafe } from "@/util/util"; import clsx from "clsx"; import { atom, PrimitiveAtom, useAtom, useAtomValue, useSetAtom } from "jotai"; import { splitAtom } from "jotai/utils"; import { OverlayScrollbarsComponent } from "overlayscrollbars-react"; -import { CSSProperties, forwardRef, memo, useCallback, useEffect, useRef, useState } from "react"; +import { CSSProperties, forwardRef, useCallback, useEffect } from "react"; import WorkspaceSVG from "../asset/workspace.svg"; import { IconButton } from "../element/iconbutton"; import { atoms, getApi } from "../store/global"; import { WorkspaceService } from "../store/services"; -import { getObjectValue, makeORef, setObjectValue } from "../store/wos"; +import { getObjectValue, makeORef } from "../store/wos"; +import { waveEventSubscribe } from "../store/wps"; +import { WorkspaceEditor } from "./workspaceeditor"; import "./workspaceswitcher.scss"; -interface ColorSelectorProps { - colors: string[]; - selectedColor?: string; - onSelect: (color: string) => void; - className?: string; -} - -const ColorSelector = memo(({ colors, selectedColor, onSelect, className }: ColorSelectorProps) => { - const handleColorClick = (color: string) => { - onSelect(color); - }; - - return ( -
- {colors.map((color) => ( -
handleColorClick(color)} - /> - ))} -
- ); -}); - -interface IconSelectorProps { - icons: string[]; - selectedIcon?: string; - onSelect: (icon: string) => void; - className?: string; -} - -const IconSelector = memo(({ icons, selectedIcon, onSelect, className }: IconSelectorProps) => { - const handleIconClick = (icon: string) => { - onSelect(icon); - }; - - return ( -
- {icons.map((icon) => { - const iconClass = makeIconClass(icon, true); - return ( - handleIconClick(icon)} - /> - ); - })} -
- ); -}); - -interface WorkspaceEditorProps { - title: string; - icon: string; - color: string; - focusInput: boolean; - onTitleChange: (newTitle: string) => void; - onColorChange: (newColor: string) => void; - onIconChange: (newIcon: string) => void; - onDeleteWorkspace: () => void; -} -const WorkspaceEditor = memo( - ({ - title, - icon, - color, - focusInput, - onTitleChange, - onColorChange, - onIconChange, - onDeleteWorkspace, - }: WorkspaceEditorProps) => { - const inputRef = useRef(null); - - const [colors, setColors] = useState([]); - const [icons, setIcons] = useState([]); - - useEffect(() => { - fireAndForget(async () => { - const colors = await WorkspaceService.GetColors(); - const icons = await WorkspaceService.GetIcons(); - setColors(colors); - setIcons(icons); - }); - }, []); - - useEffect(() => { - if (focusInput && inputRef.current) { - inputRef.current.focus(); - inputRef.current.select(); - } - }, [focusInput]); - - return ( -
- - - -
- -
-
- ); - } -); - type WorkspaceListEntry = { windowId: string; workspace: Workspace; @@ -175,15 +57,21 @@ const WorkspaceSwitcher = forwardRef((_, ref) => { setWorkspaceList(newList); }, []); + useEffect( + () => + waveEventSubscribe({ + eventType: "workspace:update", + handler: () => fireAndForget(updateWorkspaceList), + }), + [] + ); + useEffect(() => { fireAndForget(updateWorkspaceList); }, []); const onDeleteWorkspace = useCallback((workspaceId: string) => { getApi().deleteWorkspace(workspaceId); - setTimeout(() => { - fireAndForget(updateWorkspaceList); - }, 10); }, []); const isActiveWorkspaceSaved = !!(activeWorkspace.name && activeWorkspace.icon); @@ -266,9 +154,16 @@ const WorkspaceSwitcherItem = ({ const setWorkspace = useCallback((newWorkspace: Workspace) => { if (newWorkspace.name != "") { - setObjectValue({ ...newWorkspace, otype: "workspace" }, undefined, true); + fireAndForget(() => + WorkspaceService.UpdateWorkspace( + workspace.oid, + newWorkspace.name, + newWorkspace.icon, + newWorkspace.color, + false + ) + ); } - setWorkspaceEntry({ ...workspaceEntry, workspace: newWorkspace }); }, []); const isActive = !!workspaceEntry.windowId; diff --git a/pkg/service/workspaceservice/workspaceservice.go b/pkg/service/workspaceservice/workspaceservice.go index b48bafcc8..1c86ff77b 100644 --- a/pkg/service/workspaceservice/workspaceservice.go +++ b/pkg/service/workspaceservice/workspaceservice.go @@ -50,6 +50,9 @@ func (svc *WorkspaceService) UpdateWorkspace(ctx context.Context, workspaceId st return nil, fmt.Errorf("error updating workspace: %w", err) } + wps.Broker.Publish(wps.WaveEvent{ + Event: wps.Event_WorkspaceUpdate}) + updates := waveobj.ContextGetUpdatesRtn(ctx) go func() { defer panichandler.PanicHandler("WorkspaceService:UpdateWorkspace:SendUpdateEvents") diff --git a/pkg/wcore/window.go b/pkg/wcore/window.go index 53fd823c1..19dea5392 100644 --- a/pkg/wcore/window.go +++ b/pkg/wcore/window.go @@ -28,7 +28,8 @@ func SwitchWorkspace(ctx context.Context, windowId string, workspaceId string) ( if err != nil { return nil, fmt.Errorf("error getting window: %w", err) } - if window.WorkspaceId == workspaceId { + curWsId := window.WorkspaceId + if curWsId == workspaceId { return nil, nil } @@ -45,24 +46,24 @@ func SwitchWorkspace(ctx context.Context, windowId string, workspaceId string) ( return nil, err } } - - curWs, err := GetWorkspace(ctx, window.WorkspaceId) + window.WorkspaceId = workspaceId + err = wstore.DBUpdate(ctx, window) if err != nil { - return nil, fmt.Errorf("error getting current workspace: %w", err) + return nil, fmt.Errorf("error updating window: %w", err) } - deleted, err := DeleteWorkspace(ctx, curWs.OID, false) + + deleted, err := DeleteWorkspace(ctx, curWsId, false) if err != nil { return nil, fmt.Errorf("error deleting current workspace: %w", err) } if !deleted { - log.Printf("current workspace %s was not deleted\n", curWs.OID) + log.Printf("current workspace %s was not deleted\n", curWsId) } else { - log.Printf("deleted current workspace %s\n", curWs.OID) + log.Printf("deleted current workspace %s\n", curWsId) } - window.WorkspaceId = workspaceId log.Printf("switching window %s to workspace %s\n", windowId, workspaceId) - return ws, wstore.DBUpdate(ctx, window) + return ws, nil } func GetWindow(ctx context.Context, windowId string) (*waveobj.Window, error) { diff --git a/pkg/wcore/workspace.go b/pkg/wcore/workspace.go index c0b2da324..b3143b2ab 100644 --- a/pkg/wcore/workspace.go +++ b/pkg/wcore/workspace.go @@ -122,6 +122,7 @@ func DeleteWorkspace(ctx context.Context, workspaceId string, force bool) (bool, return false, fmt.Errorf("error closing tab: %w", err) } } + windowId, err := wstore.DBFindWindowForWorkspaceId(ctx, workspaceId) err = wstore.DBDelete(ctx, waveobj.OType_Workspace, workspaceId) if err != nil { return false, fmt.Errorf("error deleting workspace: %w", err) @@ -129,6 +130,12 @@ func DeleteWorkspace(ctx context.Context, workspaceId string, force bool) (bool, log.Printf("deleted workspace %s\n", workspaceId) wps.Broker.Publish(wps.WaveEvent{ Event: wps.Event_WorkspaceUpdate}) + if windowId != "" { + err = CloseWindow(ctx, windowId, false) + if err != nil { + return false, fmt.Errorf("error closing window: %w", err) + } + } return true, nil } From 95b1767c4557cf975cd2223081749e107cc5a3a2 Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Tue, 17 Dec 2024 11:55:34 -0800 Subject: [PATCH 13/35] fix terminal escape sequence printing bug (#1544) ## Summary by CodeRabbit - **Bug Fixes** - Improved handling of terminal data processing by ensuring it only occurs when the terminal is fully initialized. --- frontend/app/view/term/termwrap.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/app/view/term/termwrap.ts b/frontend/app/view/term/termwrap.ts index 84c940ca3..0ab2ea634 100644 --- a/frontend/app/view/term/termwrap.ts +++ b/frontend/app/view/term/termwrap.ts @@ -165,6 +165,9 @@ export class TermWrap { } handleTermData(data: string) { + if (!this.loaded) { + return; + } const b64data = util.stringToBase64(data); RpcApi.ControllerInputCommand(TabRpcClient, { blockid: this.blockId, inputdata64: b64data }); } From f5305cc8dd78609ad0966117a18ec64d2875b9fb Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:22:57 -0800 Subject: [PATCH 14/35] Disable Wsh on Remotes where the Domain Socket Listener Fails (#1542) A recent change meant that if certain operations for setting up wsh failed, a fallback would be employed to launch the terminal without the wsh connection. This adds the domain socket listener to the list of things that are allowed to fail before retrying without wsh instead of failing outright. --- pkg/remote/conncontroller/conncontroller.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pkg/remote/conncontroller/conncontroller.go b/pkg/remote/conncontroller/conncontroller.go index b66088923..1215be657 100644 --- a/pkg/remote/conncontroller/conncontroller.go +++ b/pkg/remote/conncontroller/conncontroller.go @@ -509,11 +509,6 @@ func (conn *SSHConn) connectInternal(ctx context.Context, connFlags *wshrpc.Conn conn.WithLock(func() { conn.Client = client }) - err = conn.OpenDomainSocketListener() - if err != nil { - log.Printf("error: unable to open domain socket listener for %s: %v\n", conn.GetName(), err) - return err - } config := wconfig.ReadFullConfig() enableWsh := config.Settings.ConnWshEnabled askBeforeInstall := config.Settings.ConnAskBeforeWshInstall @@ -545,15 +540,22 @@ func (conn *SSHConn) connectInternal(ctx context.Context, connFlags *wshrpc.Conn } if conn.WshEnabled.Load() { - csErr := conn.StartConnServer() - if csErr != nil { - log.Printf("error: unable to start conn server for %s: %v\n", conn.GetName(), csErr) + dsErr := conn.OpenDomainSocketListener() + var csErr error + if dsErr != nil { + log.Printf("error: unable to open domain socket listener for %s: %v\n", conn.GetName(), dsErr) + } else { + csErr = conn.StartConnServer() + if csErr != nil { + log.Printf("error: unable to start conn server for %s: %v\n", conn.GetName(), csErr) + } + } + if dsErr != nil || csErr != nil { log.Print("attempting to run with nowsh instead") conn.WithLock(func() { conn.WshError = csErr.Error() }) conn.WshEnabled.Store(false) - //return fmt.Errorf("conncontroller %s start wsh connserver error: %v", conn.GetName(), csErr) } } } else { From 799aecd501553662613128d83913b768857076b7 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Tue, 17 Dec 2024 13:00:55 -0800 Subject: [PATCH 15/35] Add ZDOTDIR after JWT token for WSL commands (#1546) --- pkg/shellexec/shellexec.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/shellexec/shellexec.go b/pkg/shellexec/shellexec.go index d22cdbb1f..2c811d85c 100644 --- a/pkg/shellexec/shellexec.go +++ b/pkg/shellexec/shellexec.go @@ -167,9 +167,6 @@ func StartWslShellProc(ctx context.Context, termSize waveobj.TermSize, cmdStr st homeDir := wsl.GetHomeDir(conn.Context, client) shellOpts = append(shellOpts, "~", "-d", client.Name()) - if isZshShell(shellPath) { - shellOpts = append(shellOpts, fmt.Sprintf(`ZDOTDIR="%s/.waveterm/%s"`, homeDir, shellutil.ZshIntegrationDir)) - } var subShellOpts []string if cmdStr == "" { @@ -216,6 +213,10 @@ func StartWslShellProc(ctx context.Context, termSize waveobj.TermSize, cmdStr st } else { shellOpts = append(shellOpts, "--", fmt.Sprintf(`%s=%s`, wshutil.WaveJwtTokenVarName, jwtToken)) } + + if isZshShell(shellPath) { + shellOpts = append(shellOpts, fmt.Sprintf(`ZDOTDIR="%s/.waveterm/%s"`, homeDir, shellutil.ZshIntegrationDir)) + } shellOpts = append(shellOpts, shellPath) shellOpts = append(shellOpts, subShellOpts...) log.Printf("full cmd is: %s %s", "wsl.exe", strings.Join(shellOpts, " ")) From 0a3dadb6285b2752f036c377a017a849b6ba7fe5 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Tue, 17 Dec 2024 14:11:40 -0800 Subject: [PATCH 16/35] Add `wsh wavepath` command for getting Wave paths (#1545) --- cmd/wsh/cmd/wshcmd-wavepath.go | 135 +++++++++++++++++++++++++++++ docs/docs/wsh-reference.mdx | 48 ++++++++++ frontend/app/store/wshclientapi.ts | 5 ++ frontend/layout/lib/layoutModel.ts | 5 ++ frontend/types/gotypes.d.ts | 10 +++ go.mod | 1 + go.sum | 2 + pkg/waveobj/wtype.go | 1 + pkg/wshrpc/wshclient/wshclient.go | 6 ++ pkg/wshrpc/wshrpctypes.go | 9 ++ pkg/wshrpc/wshserver/wshserver.go | 39 +++++++++ 11 files changed, 261 insertions(+) create mode 100644 cmd/wsh/cmd/wshcmd-wavepath.go diff --git a/cmd/wsh/cmd/wshcmd-wavepath.go b/cmd/wsh/cmd/wshcmd-wavepath.go new file mode 100644 index 000000000..fcfcbc7f3 --- /dev/null +++ b/cmd/wsh/cmd/wshcmd-wavepath.go @@ -0,0 +1,135 @@ +// Copyright 2024, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +package cmd + +import ( + "bytes" + "fmt" + "io" + "os" + + "github.com/spf13/cobra" + "github.com/wavetermdev/waveterm/pkg/wshrpc" + "github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient" +) + +var wavepathCmd = &cobra.Command{ + Use: "wavepath {config|data|log}", + Short: "Get paths to various waveterm files and directories", + RunE: wavepathRun, + PreRunE: preRunSetupRpcClient, +} + +func init() { + wavepathCmd.Flags().BoolP("open", "o", false, "Open the path in a new block") + wavepathCmd.Flags().BoolP("open-external", "O", false, "Open the path in the default external application") + wavepathCmd.Flags().BoolP("tail", "t", false, "Tail the last 100 lines of the log") + rootCmd.AddCommand(wavepathCmd) +} + +func wavepathRun(cmd *cobra.Command, args []string) (rtnErr error) { + defer func() { + sendActivity("wavepath", rtnErr == nil) + }() + + if len(args) == 0 { + OutputHelpMessage(cmd) + return fmt.Errorf("no arguments. wsh wavepath requires a type argument (config, data, or log)") + } + if len(args) > 1 { + OutputHelpMessage(cmd) + return fmt.Errorf("too many arguments. wsh wavepath requires exactly one argument") + } + + pathType := args[0] + if pathType != "config" && pathType != "data" && pathType != "log" { + OutputHelpMessage(cmd) + return fmt.Errorf("invalid path type %q. must be one of: config, data, log", pathType) + } + + tail, _ := cmd.Flags().GetBool("tail") + if tail && pathType != "log" { + return fmt.Errorf("--tail can only be used with the log path type") + } + + open, _ := cmd.Flags().GetBool("open") + openExternal, _ := cmd.Flags().GetBool("open-external") + + path, err := wshclient.PathCommand(RpcClient, wshrpc.PathCommandData{ + PathType: pathType, + Open: open, + OpenExternal: openExternal, + }, nil) + if err != nil { + return fmt.Errorf("getting path: %w", err) + } + + if tail && pathType == "log" { + err = tailLogFile(path) + if err != nil { + return fmt.Errorf("tailing log file: %w", err) + } + return nil + } + + WriteStdout("%s\n", path) + return nil +} + +func tailLogFile(path string) error { + file, err := os.Open(path) + if err != nil { + return fmt.Errorf("opening log file: %w", err) + } + defer file.Close() + + // Get file size + stat, err := file.Stat() + if err != nil { + return fmt.Errorf("getting file stats: %w", err) + } + + // Read last 16KB or whole file if smaller + readSize := int64(16 * 1024) + var offset int64 + if stat.Size() > readSize { + offset = stat.Size() - readSize + } + + _, err = file.Seek(offset, 0) + if err != nil { + return fmt.Errorf("seeking file: %w", err) + } + + buf := make([]byte, readSize) + n, err := file.Read(buf) + if err != nil && err != io.EOF { + return fmt.Errorf("reading file: %w", err) + } + buf = buf[:n] + + // Skip partial line at start if we're not at beginning of file + if offset > 0 { + idx := bytes.IndexByte(buf, '\n') + if idx >= 0 { + buf = buf[idx+1:] + } + } + + // Split into lines + lines := bytes.Split(buf, []byte{'\n'}) + + // Take last 100 lines if we have more + startIdx := 0 + if len(lines) > 100 { + startIdx = len(lines) - 100 + } + + // Print lines + for _, line := range lines[startIdx:] { + WriteStdout("%s\n", string(line)) + } + + return nil +} diff --git a/docs/docs/wsh-reference.mdx b/docs/docs/wsh-reference.mdx index b5c095ed5..2931c4683 100644 --- a/docs/docs/wsh-reference.mdx +++ b/docs/docs/wsh-reference.mdx @@ -693,4 +693,52 @@ wsh setvar -b client MYVAR=value Variables set with these commands persist across sessions and can be used to store configuration values, secrets, or any other string data that needs to be accessible across blocks or tabs. +## wavepath + +The `wavepath` command lets you get the paths to various Wave Terminal directories and files, including configuration, data storage, and logs. + +```bash +wsh wavepath {config|data|log} +``` + +This command returns the full path to the requested Wave Terminal system directory or file. It's useful for accessing Wave's configuration files, data storage, or checking logs. + +Flags: + +- `-o, --open` - open the path in a new block +- `-O, --open-external` - open the path in the default external application +- `-t, --tail` - show the last ~100 lines of the log file (only valid for log path) + +Examples: + +```bash +# Get path to config directory +wsh wavepath config + +# Get path to data directory +wsh wavepath data + +# Get path to log file +wsh wavepath log + +# Open log file in a new block +wsh wavepath -o log + +# Open config directory in system file explorer +wsh wavepath -O config + +# View recent log entries +wsh wavepath -t log +``` + +The command will show you the full path to: + +- `config` - Where Wave Terminal stores its configuration files +- `data` - Where Wave Terminal stores its persistent data +- `log` - The main Wave Terminal log file + +:::tip +Use the `-t` flag with the log path to quickly view recent log entries without having to open the full file. This is particularly useful for troubleshooting. +::: + diff --git a/frontend/app/store/wshclientapi.ts b/frontend/app/store/wshclientapi.ts index a5e75774d..846091596 100644 --- a/frontend/app/store/wshclientapi.ts +++ b/frontend/app/store/wshclientapi.ts @@ -202,6 +202,11 @@ class RpcApiType { return client.wshRpcCall("notify", data, opts); } + // command "path" [call] + PathCommand(client: WshClient, data: PathCommandData, opts?: RpcOpts): Promise { + return client.wshRpcCall("path", data, opts); + } + // command "remotefiledelete" [call] RemoteFileDeleteCommand(client: WshClient, data: string, opts?: RpcOpts): Promise { return client.wshRpcCall("remotefiledelete", data, opts); diff --git a/frontend/layout/lib/layoutModel.ts b/frontend/layout/lib/layoutModel.ts index 1a70fc22d..7f8479c0a 100644 --- a/frontend/layout/lib/layoutModel.ts +++ b/frontend/layout/lib/layoutModel.ts @@ -412,6 +412,11 @@ export class LayoutModel { for (const action of actions) { switch (action.actiontype) { case LayoutTreeActionType.InsertNode: { + if (action.ephemeral) { + this.newEphemeralNode(action.blockid); + break; + } + const insertNodeAction: LayoutTreeInsertNodeAction = { type: LayoutTreeActionType.InsertNode, node: newLayoutNode(undefined, undefined, undefined, { diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index afd817690..895494bda 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -139,6 +139,7 @@ declare global { blockdef: BlockDef; rtopts?: RuntimeOpts; magnified?: boolean; + ephemeral?: boolean; }; // wshrpc.CommandCreateSubBlockData @@ -400,6 +401,7 @@ declare global { indexarr?: number[]; focused: boolean; magnified: boolean; + ephemeral: boolean; }; // waveobj.LayoutState @@ -562,6 +564,14 @@ declare global { prompt: OpenAIPromptMessageType[]; }; + // wshrpc.PathCommandData + type PathCommandData = { + pathtype: string; + open: boolean; + openexternal: boolean; + tabid: string; + }; + // waveobj.Point type Point = { x: number; diff --git a/go.mod b/go.mod index c713a76c6..772c34c62 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/sawka/txwrap v0.2.0 github.com/shirou/gopsutil/v4 v4.24.11 github.com/skeema/knownhosts v1.3.0 + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/spf13/cobra v1.8.1 github.com/ubuntu/gowsl v0.0.0-20240906163211-049fd49bd93b github.com/wavetermdev/htmltoken v0.2.0 diff --git a/go.sum b/go.sum index b59c00510..8429144ec 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= diff --git a/pkg/waveobj/wtype.go b/pkg/waveobj/wtype.go index 9fa4bb3d1..af775e019 100644 --- a/pkg/waveobj/wtype.go +++ b/pkg/waveobj/wtype.go @@ -208,6 +208,7 @@ type LayoutActionData struct { IndexArr *[]int `json:"indexarr,omitempty"` Focused bool `json:"focused"` Magnified bool `json:"magnified"` + Ephemeral bool `json:"ephemeral"` } type LeafOrderEntry struct { diff --git a/pkg/wshrpc/wshclient/wshclient.go b/pkg/wshrpc/wshclient/wshclient.go index d8aa04748..3dce286c4 100644 --- a/pkg/wshrpc/wshclient/wshclient.go +++ b/pkg/wshrpc/wshclient/wshclient.go @@ -247,6 +247,12 @@ func NotifyCommand(w *wshutil.WshRpc, data wshrpc.WaveNotificationOptions, opts return err } +// command "path", wshserver.PathCommand +func PathCommand(w *wshutil.WshRpc, data wshrpc.PathCommandData, opts *wshrpc.RpcOpts) (string, error) { + resp, err := sendRpcRequestCallHelper[string](w, "path", data, opts) + return resp, err +} + // command "remotefiledelete", wshserver.RemoteFileDeleteCommand func RemoteFileDeleteCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpts) error { _, err := sendRpcRequestCallHelper[any](w, "remotefiledelete", data, opts) diff --git a/pkg/wshrpc/wshrpctypes.go b/pkg/wshrpc/wshrpctypes.go index ed5aaa7bb..71806f6b0 100644 --- a/pkg/wshrpc/wshrpctypes.go +++ b/pkg/wshrpc/wshrpctypes.go @@ -149,6 +149,7 @@ type WshRpcInterface interface { ActivityCommand(ctx context.Context, data ActivityUpdate) error GetVarCommand(ctx context.Context, data CommandVarData) (*CommandVarResponseData, error) SetVarCommand(ctx context.Context, data CommandVarData) error + PathCommand(ctx context.Context, data PathCommandData) (string, error) // connection functions ConnStatusCommand(ctx context.Context) ([]ConnStatus, error) @@ -290,6 +291,7 @@ type CommandCreateBlockData struct { BlockDef *waveobj.BlockDef `json:"blockdef"` RtOpts *waveobj.RuntimeOpts `json:"rtopts,omitempty"` Magnified bool `json:"magnified,omitempty"` + Ephemeral bool `json:"ephemeral,omitempty"` } type CommandCreateSubBlockData struct { @@ -604,6 +606,13 @@ type CommandVarResponseData struct { Exists bool `json:"exists"` } +type PathCommandData struct { + PathType string `json:"pathtype"` + Open bool `json:"open"` + OpenExternal bool `json:"openexternal"` + TabId string `json:"tabid" wshcontext:"TabId"` +} + type ActivityDisplayType struct { Width int `json:"width"` Height int `json:"height"` diff --git a/pkg/wshrpc/wshserver/wshserver.go b/pkg/wshrpc/wshserver/wshserver.go index 9e0cd1702..b4e2acfec 100644 --- a/pkg/wshrpc/wshserver/wshserver.go +++ b/pkg/wshrpc/wshserver/wshserver.go @@ -12,10 +12,12 @@ import ( "fmt" "io/fs" "log" + "path/filepath" "regexp" "strings" "time" + "github.com/skratchdot/open-golang/open" "github.com/wavetermdev/waveterm/pkg/blockcontroller" "github.com/wavetermdev/waveterm/pkg/filestore" "github.com/wavetermdev/waveterm/pkg/panichandler" @@ -183,6 +185,7 @@ func (ws *WshServer) CreateBlockCommand(ctx context.Context, data wshrpc.Command ActionType: wcore.LayoutActionDataType_Insert, BlockId: blockData.OID, Magnified: data.Magnified, + Ephemeral: data.Ephemeral, Focused: true, }) if err != nil { @@ -829,3 +832,39 @@ func (ws *WshServer) SetVarCommand(ctx context.Context, data wshrpc.CommandVarDa envStr := envutil.MapToEnv(envMap) return filestore.WFS.WriteFile(ctx, data.ZoneId, data.FileName, []byte(envStr)) } + +func (ws *WshServer) PathCommand(ctx context.Context, data wshrpc.PathCommandData) (string, error) { + pathType := data.PathType + openInternal := data.Open + openExternal := data.OpenExternal + var path string + switch pathType { + case "config": + path = wavebase.GetWaveConfigDir() + case "data": + path = wavebase.GetWaveDataDir() + case "log": + path = filepath.Join(wavebase.GetWaveDataDir(), "waveapp.log") + } + + if openInternal && openExternal { + return "", fmt.Errorf("open and openExternal cannot both be true") + } + + if openInternal { + _, err := ws.CreateBlockCommand(ctx, wshrpc.CommandCreateBlockData{BlockDef: &waveobj.BlockDef{Meta: map[string]any{ + waveobj.MetaKey_View: "preview", + waveobj.MetaKey_File: path, + }}, Ephemeral: true, TabId: data.TabId}) + + if err != nil { + return path, fmt.Errorf("error opening path: %w", err) + } + } else if openExternal { + err := open.Run(path) + if err != nil { + return path, fmt.Errorf("error opening path: %w", err) + } + } + return path, nil +} From a06ba64e2f167d15a132ab0d93b03a62bf7ea4a9 Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Tue, 17 Dec 2024 14:23:27 -0800 Subject: [PATCH 17/35] document markdown font size settings (#1547) ## Summary by CodeRabbit - **New Features** - Introduced new configuration options for markdown rendering: - `markdown:fontsize` for normal text size (default 14px). - `markdown:fixedfontsize` for code block text size (default 12px). --- docs/docs/config.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/docs/config.mdx b/docs/docs/config.mdx index c72095558..c960d8be5 100644 --- a/docs/docs/config.mdx +++ b/docs/docs/config.mdx @@ -46,6 +46,8 @@ wsh editconfig | editor:minimapenabled | bool | set to false to disable editor minimap | | editor:stickyscrollenabled | bool | enables monaco editor's stickyScroll feature (pinning headers of current context, e.g. class names, method names, etc.), defaults to false | | editor:wordwrap | bool | set to true to enable word wrapping in the editor (defaults to false) | +| markdown:fontsize | float64 | font size for the normal text when rendering markdown in preview. headers are scaled up from this size, (default 14px) | +| markdown:fixedfontsize | float64 | font size for the code blocks when rendering markdown in preview (default is 12px) | | web:openlinksinternally | bool | set to false to open web links in external browser | | web:defaulturl | string | default web page to open in the web widget when no url is provided (homepage) | | web:defaultsearch | string | search template for web searches. e.g. `https://www.google.com/search?q={query}`. "\{query}" gets replaced by search term | From 801034c87d0856051bdbd6375bf0c4c8b15f74b8 Mon Sep 17 00:00:00 2001 From: "wave-builder[bot]" <181805596+wave-builder[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:24:41 +0000 Subject: [PATCH 18/35] chore: bump package version to 0.10.2-beta.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cdb5a81ca..6497727ea 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "productName": "Wave", "description": "Open-Source AI-Native Terminal Built for Seamless Workflows", "license": "Apache-2.0", - "version": "0.10.1", + "version": "0.10.2-beta.0", "homepage": "https://waveterm.dev", "build": { "appId": "dev.commandline.waveterm" From dbc2be1c1e9272a948ad08c20666af307eddb24c Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Tue, 17 Dec 2024 15:25:34 -0800 Subject: [PATCH 19/35] Global Hotkey Docs (#1548) Adds the following changes: - renames "key:globalhotkey" to "app:globalhotkey" - adds globalhostkey documentation (especially in regard to what keys are allowed) - improves the algorithm that converts electron keybindings from wave keybindings - fixes some regexp problems --- docs/docs/config.mdx | 42 ++++++++++++++++++++++ docs/docs/keybindings.mdx | 4 +++ emain/emain-util.ts | 66 +++++++++++++++++++++++++++++++++++ emain/emain.ts | 2 +- frontend/types/gotypes.d.ts | 4 +-- pkg/wconfig/metaconsts.go | 6 ++-- pkg/wconfig/settingsconfig.go | 6 ++-- 7 files changed, 121 insertions(+), 9 deletions(-) diff --git a/docs/docs/config.mdx b/docs/docs/config.mdx index c960d8be5..49cada776 100644 --- a/docs/docs/config.mdx +++ b/docs/docs/config.mdx @@ -25,6 +25,7 @@ wsh editconfig | Key Name | Type | Function | | ------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| app:globalhotkey | string | A systemwide keybinding to open your most recent wave window. This is a set of key names separated by `:`. For more info, see [Customizable Systemwide Global Hotkey](#customizable-systemwide-global-hotkey) | | ai:preset | string | the default AI preset to use | | ai:baseurl | string | Set the AI Base Url (must be OpenAI compatible) | | ai:apitoken | string | your AI api token | @@ -190,3 +191,44 @@ wsh editconfig termthemes.json | background | CSS color | | | background color (default when no color code is applied), must have alpha channel (#rrggbbaa) if you want the terminal to be transparent | | cursorAccent | CSS color | | | color for cursor | | selectionBackground | CSS color | | | background color for selected text | + +### Customizable Systemwide Global Hotkey + +Wave allows settings a custom global hotkey to open your most recent window from anywhere in your computer. This has the name `"app:globalhotkey"` in the `settings.json` file and takes the form of a series of key names separated by the `:` character. We support the following key names: + +- `Ctrl` +- `Cmd` +- `Shift` +- `Alt` +- `Option` +- `Meta` +- `Super` +- Digits (non-numpad) represented by `c{Digit0}` through `c{Digit9}` +- Letters `a` though `z` +- F keys `F1` through `F20` +- Soft keys `Soft1` through `Soft4`. These are essentially the same as `F21` through `F24`. +- Space represented as a literal space    +- `Enter` (This is labeled as return on Mac) +- `Tab` +- `CapsLock` +- `NumLock` +- `Backspace` (This is labeled as delete on Mac) +- `Delete` +- `Insert` +- The arrow keys `ArrowUp`, `ArrowDown`, `ArrowLeft`, and `ArrowRight` +- `Home` +- `End` +- `PageUp` +- `PageDown` +- `Esc` +- Volume controls `AudioVolumeUp`, `AudioVolumeDown`, `AudioVolumeMute` +- Media controls `MediaTrackNext`, `MediaTrackPrevious`, `MediaPlayPause`, and `MediaStop` +- `PrintScreen` +- Numpad keys represented by `c{Numpad0}` through `c{Numpad9}` +- The numpad decimal represented by `Decimal` +- The numpad plus/add represented by `Add` +- The numpad minus/subtract represented by `Subtract` +- The numpad star/multiply represented by `Multiply` +- The numpad slash/divide represented by `Divide` + +As an example, to set the key to the combination of Control, Option, and the letter E, you would configure it to `"Ctrl:Opt:e"`. diff --git a/docs/docs/keybindings.mdx b/docs/docs/keybindings.mdx index 2313bacc3..cfb1569e5 100644 --- a/docs/docs/keybindings.mdx +++ b/docs/docs/keybindings.mdx @@ -71,4 +71,8 @@ replace "Cmd" with "Alt" (note that "Ctrl" is "Ctrl" on both Mac, Windows, and L | ---------------- | ------------- | | | Clear AI Chat | +## Customizeable Systemwide Global Hotkey + +Wave allows setting a custom global hotkey to focus your most recent window from anywhere in your computer. For more information on this, see [the config docs](./config#customizable-systemwide-global-hotkey). + diff --git a/emain/emain-util.ts b/emain/emain-util.ts index 16fbf9367..601b1b7f3 100644 --- a/emain/emain-util.ts +++ b/emain/emain-util.ts @@ -170,6 +170,9 @@ export function ensureBoundsAreVisible(bounds: electron.Rectangle): electron.Rec export function waveKeyToElectronKey(waveKey: string): string { const waveParts = waveKey.split(":"); const electronParts: Array = waveParts.map((part: string) => { + const digitRegexpMatch = new RegExp("^c{Digit([0-9])}$").exec(part); + const numpadRegexpMatch = new RegExp("^c{Numpad([0-9])}$").exec(part); + const lowercaseCharMatch = new RegExp("^([a-z])$").exec(part); if (part == "ArrowUp") { return "Up"; } @@ -182,6 +185,69 @@ export function waveKeyToElectronKey(waveKey: string): string { if (part == "ArrowRight") { return "Right"; } + if (part == "Soft1") { + return "F21"; + } + if (part == "Soft2") { + return "F22"; + } + if (part == "Soft3") { + return "F23"; + } + if (part == "Soft4") { + return "F24"; + } + if (part == " ") { + return "Space"; + } + if (part == "CapsLock") { + return "Capslock"; + } + if (part == "NumLock") { + return "Numlock"; + } + if (part == "ScrollLock") { + return "Scrolllock"; + } + if (part == "AudioVolumeUp") { + return "VolumeUp"; + } + if (part == "AudioVolumeDown") { + return "VolumeDown"; + } + if (part == "AudioVolumeMute") { + return "VolumeMute"; + } + if (part == "MediaTrackNext") { + return "MediaNextTrack"; + } + if (part == "MediaTrackPrevious") { + return "MediaPreviousTrack"; + } + if (part == "Decimal") { + return "numdec"; + } + if (part == "Add") { + return "numadd"; + } + if (part == "Subtract") { + return "numsub"; + } + if (part == "Multiply") { + return "nummult"; + } + if (part == "Divide") { + return "numdiv"; + } + if (digitRegexpMatch && digitRegexpMatch.length > 1) { + return digitRegexpMatch[1]; + } + if (numpadRegexpMatch && numpadRegexpMatch.length > 1) { + return `num${numpadRegexpMatch[1]}`; + } + if (lowercaseCharMatch && lowercaseCharMatch.length > 1) { + return lowercaseCharMatch[1].toUpperCase(); + } return part; }); diff --git a/emain/emain.ts b/emain/emain.ts index c5cf985be..a4511db45 100644 --- a/emain/emain.ts +++ b/emain/emain.ts @@ -611,7 +611,7 @@ async function appMain() { fireAndForget(createNewWaveWindow); } }); - const rawGlobalHotKey = launchSettings?.["key:globalhotkey"]; + const rawGlobalHotKey = launchSettings?.["app:globalhotkey"]; if (rawGlobalHotKey) { registerGlobalHotkey(rawGlobalHotKey); } diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 895494bda..c0149d01e 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -616,6 +616,8 @@ declare global { // wconfig.SettingsType type SettingsType = { + "app:*"?: boolean; + "app:globalhotkey"?: string; "ai:*"?: boolean; "ai:preset"?: string; "ai:apitype"?: string; @@ -674,8 +676,6 @@ declare global { "window:magnifiedblocksize"?: number; "window:magnifiedblockblurprimarypx"?: number; "window:magnifiedblockblursecondarypx"?: number; - "key:*"?: boolean; - "key:globalhotkey"?: string; "telemetry:*"?: boolean; "telemetry:enabled"?: boolean; "conn:*"?: boolean; diff --git a/pkg/wconfig/metaconsts.go b/pkg/wconfig/metaconsts.go index 6e62b5c20..7e95579ad 100644 --- a/pkg/wconfig/metaconsts.go +++ b/pkg/wconfig/metaconsts.go @@ -6,6 +6,9 @@ package wconfig const ( + ConfigKey_AppClear = "app:*" + ConfigKey_AppGlobalHotkey = "app:globalhotkey" + ConfigKey_AiClear = "ai:*" ConfigKey_AiPreset = "ai:preset" ConfigKey_AiApiType = "ai:apitype" @@ -75,9 +78,6 @@ const ( ConfigKey_WindowMagnifiedBlockBlurPrimaryPx = "window:magnifiedblockblurprimarypx" ConfigKey_WindowMagnifiedBlockBlurSecondaryPx = "window:magnifiedblockblursecondarypx" - ConfigKey_KeyClear = "key:*" - ConfigKey_KeyGlobalHotkey = "key:globalhotkey" - ConfigKey_TelemetryClear = "telemetry:*" ConfigKey_TelemetryEnabled = "telemetry:enabled" diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index 6b9e58319..8b312db4b 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -33,6 +33,9 @@ const AnySchema = ` ` type SettingsType struct { + AppClear bool `json:"app:*,omitempty"` + AppGlobalHotkey string `json:"app:globalhotkey,omitempty"` + AiClear bool `json:"ai:*,omitempty"` AiPreset string `json:"ai:preset,omitempty"` AiApiType string `json:"ai:apitype,omitempty"` @@ -102,9 +105,6 @@ type SettingsType struct { WindowMagnifiedBlockBlurPrimaryPx *int64 `json:"window:magnifiedblockblurprimarypx,omitempty"` WindowMagnifiedBlockBlurSecondaryPx *int64 `json:"window:magnifiedblockblursecondarypx,omitempty"` - KeyClear bool `json:"key:*,omitempty"` - KeyGlobalHotkey string `json:"key:globalhotkey,omitempty"` - TelemetryClear bool `json:"telemetry:*,omitempty"` TelemetryEnabled bool `json:"telemetry:enabled,omitempty"` From 69bb1d4274a7f1c87e14042b87cafb4df9383f1c Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:06:34 -0800 Subject: [PATCH 20/35] Fish and Pwsh Examples (#1549) This adds example widgets to the docs for fish and powershell core (pwsh) --- docs/docs/customwidgets.mdx | 60 +++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/docs/docs/customwidgets.mdx b/docs/docs/customwidgets.mdx index ca61fdb0f..8f693ee58 100644 --- a/docs/docs/customwidgets.mdx +++ b/docs/docs/customwidgets.mdx @@ -109,9 +109,65 @@ The `WidgetConfigType` takes the usual options common to all widgets. The `MetaT | "term:localshellpath" | (optional) Sets the shell used for running your widget command. Only works locally. If left blank, wave will determine your system default instead. | | "term:localshellopts" | (optional) Sets the shell options meant to be used with `"term:localshellpath"`. This is useful if you are using a nonstandard shell and need to provide a specific option that we do not cover. Only works locally. Defaults to an empty string. | -## Example Terminal Widgets +## Example Shell Widgets -Here are a few simple widgets to serve as examples. +If you have multiple shells installed on your machine, there may be times when you want to use a non-default shell. For cases like this, it is easy to create a widget for each. + +Suppose you want a widget to launch a `fish` shell. Once you have `fish` installed on your system, you can define a widget as + +```json +{ + <... other widgets go here ...>, + "fish" : { + "icon": "fish", + "color": "#4abc39", + "label": "fish", + "blockdef": { + "meta": { + "view": "term", + "controller": "shell", + "term:localshellpath": "/usr/local/bin/fish", + "term:localshellopts": "-i -l" + } + } + }, + <... other widgets go here ...> +} +``` + +:::info +It is very possible that `fish` is not in your path. In this case, using `"fish"` as the value of `"term:localshellpath"` will not work. In these cases, you will need to provide a direct path to it. This is often somewhere like `"/usr/local/bin/fish"`, but it may be different on your system. +::: + +If you want to do the same for something like Powershell Core, or `pwsh`, you can define the widget as + +```json +{ + <... other widgets go here ...>, + "pwsh" : { + "icon": "rectangle-terminal", + "color": "#2671be", + "label": "pwsh", + "blockdef": { + "meta": { + "view": "term", + "controller": "shell", + "term:localshellpath": "pwsh" + } + } + }, + <... other widgets go here ...> +} +``` + +:::info +It is very possible that `pwsh` is not in your path. In this case, using `"pwsh"` as the value of `"term:localshellpath"` will not work. In these cases, you will need to provide a direct path to it. This could be somewhere like `"/usr/local/bin/pwsh"` on a Unix system or "C:\\Program Files\\PowerShell\\7\\pwsh.exe" on +Windows. but it may be different on your system. Also note that both `pwsh.exe` and `pwsh` work on Windows, but only `pwsh` works on Unix systems. +::: + +## Example Cmd Widgets + +Here are a few simple cmd widgets to serve as examples. Suppose I want a widget that will run speedtest-go when opened. Then, I can define a widget as From 410c01cae32ecd69339320c04b36f556521eb77f Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:19:15 -0800 Subject: [PATCH 21/35] Connections Examples (#1552) Adds a few examples to the `connections.mdx` file to show: - hiding a connection - re-ordering connections - theming connections - disabling wsh for a connection --- docs/docs/connections.mdx | 66 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/docs/docs/connections.mdx b/docs/docs/connections.mdx index 4fb79ba62..066410a92 100644 --- a/docs/docs/connections.mdx +++ b/docs/docs/connections.mdx @@ -76,6 +76,72 @@ In addition to the regular ssh config file, wave also has its own config file to | term:theme | This string can be used to specify a terminal theme for blocks using this connection. The block metadata takes priority over this setting. It defaults to null which means the global setting will be used instead. | | ssh:identityfile | A list of strings containing the paths to identity files that will be used. If a `wsh ssh` command using the `-i` flag is successful, the identity file will automatically be added here. | +### Example Internal Configurations + +Here are a couple examples of things you can do using the internal configuration file `connections.json`: + +#### Hiding a Connection + +Suppose you have a connection named `github.com` in your `~/.ssh/config` file that shows up as `git@github.com` in the connections dropdown. While it does belong in the config file for authentication reasons, it makes no sense to be in the dropdown since it doesn't involve connecting to a remote environment. In that case, you can hide it as in the example below: + +```json +{ + <... other connections go here ...>, + "git@github.com" : { + "display:hidden": true + }, + <... other connections go here ...> +} +``` + +#### Moving a Connection + +Suppose you have a connection named `rarelyused` that shows up as `myusername@rarelyused:9999` in the connections dropdown. Since it's so rarely used, you would prefer to move it later in the list. In that case, you can move it as in the example below: + +```json +{ + <... other connections go here ...>, + "myusername@rarelyused:9999" : { + "display:order": 100 + }, + <... other connections go here ...> +} +``` + +#### Theming a Connection + +Suppose you have a connection named `myhost` that shows up as `myusername@myhost` in the connections dropdown. You use this connection a lot, but you keep getting it mixed up with your local connections. In this case, you can use the internal configuration file to style it differently. For example: + +```json +{ + <... other connections go here ...>, + "myusername@myhost" : { + "term:theme": "warmyellow", + "term:fontsize": 16, + "term:fontfamily": "menlo" + }, + <... other connections go here ...> +} +``` + +This style, font size, and font family will then only apply to the widgets that are using this connection. + +### Disabling Wsh for a Connection + +While Wave provides an option disable `wsh` when first connecting to a remote, there are cases where you may wish to disable it afterward. The easiest way to do this is by editing the `connections.json` file. Suppose the connection shows up in the dropdown as `root@wshless`. Then you can disable it manually with the following line: + +```json +{ + <... other connections go here ...>, + "root@wshless" : { + "conn:enablewsh": false, + }, + <... other connections go here ...> +} +``` + +Note that this same line gets added to your `connections.json` file automatically when you choose to disable `wsh` in gui when initially connecting. + ## Managing Connections with the CLI The `wsh` command gives some commands specifically for interacting with the connections. You can view these [here](/wsh-reference#conn). From cc6da280323964066a6b0ab5537e47092033a87c Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Wed, 18 Dec 2024 08:14:27 -0800 Subject: [PATCH 22/35] Add FAQ for WSH outside of Wave (#1558) Adds FAQ explaining that WSH doesn't work outside of Wave --- docs/docs/faq.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/docs/faq.mdx b/docs/docs/faq.mdx index dac3754ed..d8b84a151 100644 --- a/docs/docs/faq.mdx +++ b/docs/docs/faq.mdx @@ -30,3 +30,7 @@ Just remember in JSON, backslashes need to be escaped. So add this to your [sett ```json "term:localshellpath": "C:\\Program Files\\Git\\bin\\bash.exe" ``` + +### Can I use WSH outside of Wave? + +`wsh` is an internal CLI for extending control over Wave to the command line, you can learn more about it [here](./wsh). To prevent misuse by other applications, `wsh` requires an access token provided by Wave to work and will not function outside of the app. From 007c2391f1369971c732557a4de4b517490555a4 Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Wed, 18 Dec 2024 13:15:28 -0800 Subject: [PATCH 23/35] Shell Example Pictures (#1562) - adds pictures to the fish and pwsh examples - reformats some tabs as spaces in the example json - adds missing brackets around some older json examples - rewords repetitive parts of the shell examples --- docs/docs/customwidgets.mdx | 70 +++++++++++++++---------- docs/docs/img/widget-example-fish.webp | Bin 0 -> 130078 bytes docs/docs/img/widget-example-pwsh.webp | Bin 0 -> 132266 bytes 3 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 docs/docs/img/widget-example-fish.webp create mode 100644 docs/docs/img/widget-example-pwsh.webp diff --git a/docs/docs/customwidgets.mdx b/docs/docs/customwidgets.mdx index 8f693ee58..44e6a95d0 100644 --- a/docs/docs/customwidgets.mdx +++ b/docs/docs/customwidgets.mdx @@ -118,25 +118,28 @@ Suppose you want a widget to launch a `fish` shell. Once you have `fish` install ```json { <... other widgets go here ...>, - "fish" : { - "icon": "fish", - "color": "#4abc39", - "label": "fish", - "blockdef": { - "meta": { - "view": "term", - "controller": "shell", - "term:localshellpath": "/usr/local/bin/fish", - "term:localshellopts": "-i -l" - } - } - }, + "fish" : { + "icon": "fish", + "color": "#4abc39", + "label": "fish", + "blockdef": { + "meta": { + "view": "term", + "controller": "shell", + "term:localshellpath": "/usr/local/bin/fish", + "term:localshellopts": "-i -l" + } + } + }, <... other widgets go here ...> } ``` +This adds an icon to the widget bar that you can press to launch a terminal running the `fish` shell. +![The example fish widget](./img/widget-example-fish.webp) + :::info -It is very possible that `fish` is not in your path. In this case, using `"fish"` as the value of `"term:localshellpath"` will not work. In these cases, you will need to provide a direct path to it. This is often somewhere like `"/usr/local/bin/fish"`, but it may be different on your system. +It is possible that `fish` is not in your path. If this is true, using `"fish"` as the value of `"term:localshellpath"` will not work. In these cases, you will need to provide a direct path to it. This is often somewhere like `"/usr/local/bin/fish"`, but it may be different on your system. ::: If you want to do the same for something like Powershell Core, or `pwsh`, you can define the widget as @@ -144,24 +147,27 @@ If you want to do the same for something like Powershell Core, or `pwsh`, you ca ```json { <... other widgets go here ...>, - "pwsh" : { - "icon": "rectangle-terminal", - "color": "#2671be", - "label": "pwsh", - "blockdef": { - "meta": { - "view": "term", - "controller": "shell", - "term:localshellpath": "pwsh" - } - } - }, + "pwsh" : { + "icon": "rectangle-terminal", + "color": "#2671be", + "label": "pwsh", + "blockdef": { + "meta": { + "view": "term", + "controller": "shell", + "term:localshellpath": "pwsh" + } + } + }, <... other widgets go here ...> } ``` +This adds an icon to the widget bar that you can press to launch a terminal running the `pwsh` shell. +![The example pwsh widget](./img/widget-example-pwsh.webp) + :::info -It is very possible that `pwsh` is not in your path. In this case, using `"pwsh"` as the value of `"term:localshellpath"` will not work. In these cases, you will need to provide a direct path to it. This could be somewhere like `"/usr/local/bin/pwsh"` on a Unix system or "C:\\Program Files\\PowerShell\\7\\pwsh.exe" on +It is possible that `pwsh` is not in your path. If this is true, using `"pwsh"` as the value of `"term:localshellpath"` will not work. In these cases, you will need to provide a direct path to it. This could be somewhere like `"/usr/local/bin/pwsh"` on a Unix system or "C:\\Program Files\\PowerShell\\7\\pwsh.exe" on Windows. but it may be different on your system. Also note that both `pwsh.exe` and `pwsh` work on Windows, but only `pwsh` works on Unix systems. ::: @@ -198,6 +204,7 @@ Using `"cmd"` for the `"controller"` is the simplest way to accomplish this. `"c Now suppose I wanted to run a TUI app, for instance, `dua`. Well, it turns out that you can more or less do the same thing: ```json +{ <... other widgets go here ...>, "dua" : { "icon": "brands@linux", @@ -211,6 +218,7 @@ Now suppose I wanted to run a TUI app, for instance, `dua`. Well, it turns out t } }, <... other widgets go here ...> +} ``` This adds an icon to the widget bar that you can press to launch a terminal running the `dua` command. @@ -252,6 +260,7 @@ The `WidgetConfigType` takes the usual options common to all widgets. The `MetaT Say you want a widget that automatically starts at YouTube and will use YouTube as the home page. This can be done using: ```json +{ <... other widgets go here ...>, "youtube" : { "icon": "brands@youtube", @@ -265,6 +274,7 @@ Say you want a widget that automatically starts at YouTube and will use YouTube } }, <... other widgets go here ...> +} ``` This adds an icon to the widget bar that you can press to launch a web widget on the youtube homepage. @@ -273,6 +283,7 @@ This adds an icon to the widget bar that you can press to launch a web widget on Alternatively, say you want a web widget that opens to github as if it were a bookmark, but will use google as its home page after that. This can easily be done with: ```json +{ <... other widgets go here ...>, "github" : { "icon": "brands@github", @@ -286,6 +297,7 @@ Alternatively, say you want a web widget that opens to github as if it were a bo } }, <... other widgets go here ...> +} ``` This adds an icon to the widget bar that you can press to launch a web widget on the github homepage. @@ -326,6 +338,7 @@ The `WidgetConfigType` takes the usual options common to all widgets. The `MetaT Suppose you have a build process that lasts 3 minutes and you'd like to be able to see the entire build on the sysinfo graph. Also, you would really like to view both the cpu and memory since both are impacted by this process. In that case, you can set up a widget as follows: ```json +{ <... other widgets go here ...>, "3min-info" : { "icon": "circle-3", @@ -339,6 +352,7 @@ Suppose you have a build process that lasts 3 minutes and you'd like to be able } }, <... other widgets go here ...> +} ``` This adds an icon to the widget bar that you can press to launch the CPU and Memory plots by default with 180 seconds of data. @@ -347,6 +361,7 @@ This adds an icon to the widget bar that you can press to launch the CPU and Mem Now, suppose you are fine with the default 100 points (and 100 seconds) but would like to show all of the CPU data when launched. In that case, you can write: ```json +{ <... other widgets go here ...>, "all-cpu" : { "icon": "chart-scatter", @@ -359,6 +374,7 @@ Now, suppose you are fine with the default 100 points (and 100 seconds) but woul } }, <... other widgets go here ...> +} ``` This adds an icon to the widget bar that you can press to launch All CPU plots by default. diff --git a/docs/docs/img/widget-example-fish.webp b/docs/docs/img/widget-example-fish.webp new file mode 100644 index 0000000000000000000000000000000000000000..0819ce981d02455283f4d983b42a1146bd85b0b6 GIT binary patch literal 130078 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/docs/img/widget-example-pwsh.webp b/docs/docs/img/widget-example-pwsh.webp new file mode 100644 index 0000000000000000000000000000000000000000..3eb46f1e738e439ff4250775bc7d4a020bc6d74b GIT binary patch literal 132266 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 E0}gdM%K!iX literal 0 HcmV?d00001 From 9f471cfde638922665a08aa20567baf52b44fc5d Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:57:52 -0800 Subject: [PATCH 24/35] Better Hotkey Example (#1563) - adds a more practical example - moves the examples above this list of allowed keys - adds the word "Space" as an option for the space character to the docs ## Summary by CodeRabbit - **Documentation** - Updated the configuration documentation for improved clarity and additional examples. - Expanded section on customizable global hotkeys with practical examples. - Clarified representation of the space key in allowed key names. --- docs/docs/config.mdx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/docs/config.mdx b/docs/docs/config.mdx index 49cada776..b06be4151 100644 --- a/docs/docs/config.mdx +++ b/docs/docs/config.mdx @@ -194,7 +194,17 @@ wsh editconfig termthemes.json ### Customizable Systemwide Global Hotkey -Wave allows settings a custom global hotkey to open your most recent window from anywhere in your computer. This has the name `"app:globalhotkey"` in the `settings.json` file and takes the form of a series of key names separated by the `:` character. We support the following key names: +Wave allows settings a custom global hotkey to open your most recent window from anywhere in your computer. This has the name `"app:globalhotkey"` in the `settings.json` file and takes the form of a series of key names separated by the `:` character. + +#### Examples + +As a practical example, suppose you want a value of `F5` as your global hotkey. Then you can simply set the value of `"app:globalhotkey"` to `"F5"` and reboot Wave to make that your global hotkey. + +As a less practical example, suppose you use the combination of the keys `Ctrl`, `Option`, and `e`. Then the value for this keybinding would be `"Ctrl:Option:e"`. + +#### Allowed Key Names + +We support the following key names: - `Ctrl` - `Cmd` @@ -207,7 +217,7 @@ Wave allows settings a custom global hotkey to open your most recent window from - Letters `a` though `z` - F keys `F1` through `F20` - Soft keys `Soft1` through `Soft4`. These are essentially the same as `F21` through `F24`. -- Space represented as a literal space    +- Space represented as either `Space` or a literal space    - `Enter` (This is labeled as return on Mac) - `Tab` - `CapsLock` @@ -230,5 +240,3 @@ Wave allows settings a custom global hotkey to open your most recent window from - The numpad minus/subtract represented by `Subtract` - The numpad star/multiply represented by `Multiply` - The numpad slash/divide represented by `Divide` - -As an example, to set the key to the combination of Control, Option, and the letter E, you would configure it to `"Ctrl:Opt:e"`. From 0925af530091fec80bf76eb0ace555068ed46a00 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Wed, 18 Dec 2024 19:44:50 -0800 Subject: [PATCH 25/35] Add warning when user is running in ARM translation mode (#1560) Adds warning and docs to let users know when they're running in ARM translation mode. Also lets them configure to always dismiss if they don't care. ## Summary by CodeRabbit - **New Features** - Added a configuration option to dismiss architecture warnings during application startup. - Introduced new FAQs addressing ARM64 translation warnings and instructions for joining beta builds. - Added platform-specific requirements for macOS, Windows, and Linux in the getting started documentation. - **Bug Fixes** - Enhanced build command flexibility by allowing dynamic command-line arguments during the build process. - **Documentation** - Updated configuration documentation to include the new dismiss architecture warning key. - Minor formatting adjustments in FAQs and getting started documentation. - Clarified platform compatibility details in the README. - **Chores** - Added a new constant for the dismiss architecture warning configuration key. - Introduced a new field for managing architecture warning settings in the application configuration. --- README.md | 8 +++++++- Taskfile.yml | 2 +- docs/docs/config.mdx | 1 + docs/docs/faq.mdx | 25 ++++++++++++++++++++++++- docs/docs/gettingstarted.mdx | 29 +++++++++++++++++++++++++++++ emain/emain.ts | 2 ++ emain/platform.ts | 29 ++++++++++++++++++++++++++++- frontend/types/gotypes.d.ts | 1 + pkg/wconfig/metaconsts.go | 1 + pkg/wconfig/settingsconfig.go | 5 +++-- 10 files changed, 97 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 529fdee26..28f2004d3 100644 --- a/README.md +++ b/README.md @@ -41,12 +41,18 @@ You can also install Wave Terminal directly from: [www.waveterm.dev/download](ht ### Minimum requirements -Wave Terminal and WSH run on the following platforms: +Wave Terminal runs on the following platforms: - macOS 11 or later (arm64, x64) - Windows 10 1809 or later (x64) - Linux based on glibc-2.28 or later (Debian 10, RHEL 8, Ubuntu 20.04, etc.) (arm64, x64) +The WSH helper runs on the following platforms: + +- macOS 11 or later (arm64, x64) +- Windows 10 or later (arm64, x64) +- Linux Kernel 2.6.32 or later (x64), Linux Kernel 3.1 or later (arm64) + ## Links - Homepage — https://www.waveterm.dev diff --git a/Taskfile.yml b/Taskfile.yml index 98af8336a..beb8622e7 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -96,7 +96,7 @@ tasks: cmds: - cmd: '{{.RMRF}} "make"' ignore_error: true - - yarn build:prod && yarn electron-builder -c electron-builder.config.cjs -p never + - yarn build:prod && yarn electron-builder -c electron-builder.config.cjs -p never {{.CLI_ARGS}} deps: - yarn - docsite:build:embedded diff --git a/docs/docs/config.mdx b/docs/docs/config.mdx index b06be4151..c97ef839b 100644 --- a/docs/docs/config.mdx +++ b/docs/docs/config.mdx @@ -26,6 +26,7 @@ wsh editconfig | Key Name | Type | Function | | ------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | app:globalhotkey | string | A systemwide keybinding to open your most recent wave window. This is a set of key names separated by `:`. For more info, see [Customizable Systemwide Global Hotkey](#customizable-systemwide-global-hotkey) | +| app:dismissarchitecturewarning | bool | Disable warnings on app start when you are using a non-native architecture for Wave. For more info, see [Why does Wave warn me about ARM64 translation when it launches?](./faq#why-does-wave-warn-me-about-arm64-translation-when-it-launches). | | ai:preset | string | the default AI preset to use | | ai:baseurl | string | Set the AI Base Url (must be OpenAI compatible) | | ai:apitoken | string | your AI api token | diff --git a/docs/docs/faq.mdx b/docs/docs/faq.mdx index d8b84a151..08797f690 100644 --- a/docs/docs/faq.mdx +++ b/docs/docs/faq.mdx @@ -28,9 +28,32 @@ the location of the Git Bash "bash.exe" binary. By default it is located at "C:\ Just remember in JSON, backslashes need to be escaped. So add this to your [settings.json](./config) file: ```json - "term:localshellpath": "C:\\Program Files\\Git\\bin\\bash.exe" +"term:localshellpath": "C:\\Program Files\\Git\\bin\\bash.exe" ``` ### Can I use WSH outside of Wave? `wsh` is an internal CLI for extending control over Wave to the command line, you can learn more about it [here](./wsh). To prevent misuse by other applications, `wsh` requires an access token provided by Wave to work and will not function outside of the app. + +## Why does Wave warn me about ARM64 translation when it launches? + +macOS and Windows both have compatibility layers that allow x64 applications to run on ARM computers. This helps more apps run on these systems while developers work to add native ARM support to their applications. However, it comes with significant performance tradeoffs. + +To get the best experience using Wave, it is recommended that you uninstall Wave and reinstall the version that is natively compiled for your computer. You can find the right version by consulting our [Installation Instructions](./gettingstarted#installation). + +You can disable this warning by setting `app:dismissarchitecturewarning=true` in [your configurations](./config.mdx). + +## How do I join the beta builds of Wave? + +Wave publishes to two channels, `latest` and `beta`. If you've installed the app for macOS, Windows, or Linux via DEB or RPM, you can set the following configurations in your `settings.json` (see [Configuration](./config) for more info): + +```json +"autoupdate:enabled": true, +"autoupdate:channel": "beta" +``` + +If you've installed via Snap, you can use the following command: + +```sh +sudo snap install waveterm --classic --beta +``` diff --git a/docs/docs/gettingstarted.mdx b/docs/docs/gettingstarted.mdx index 9330ed77f..47e8c0273 100644 --- a/docs/docs/gettingstarted.mdx +++ b/docs/docs/gettingstarted.mdx @@ -14,6 +14,35 @@ Wave Terminal is a modern terminal that includes graphical capabilities like web +### Platform requirements + + + +- Supported architectures: Apple Silicon, x64 +- Supported OS version: macOS 11 Big Sur or later + + + + + +- Supported architectures: x64 +- Supported OS version: Windows 10 1809 or later, Windows 11 + +:::note + +ARM64 is planned, but is currently blocked by upstream dependencies (see [Windows ARM Support](https://github.com/wavetermdev/waveterm/issues/928)). + +::: + + + + + +- Supported architectures: x64, ARM64 +- Supported OS version: must have glibc-2.28 or later (Debian >=10, RHEL >=8, Ubuntu >=20.04, etc.) + + + ### Package managers diff --git a/emain/emain.ts b/emain/emain.ts index a4511db45..157033588 100644 --- a/emain/emain.ts +++ b/emain/emain.ts @@ -47,6 +47,7 @@ import { getLaunchSettings } from "./launchsettings"; import { log } from "./log"; import { makeAppMenu } from "./menu"; import { + checkIfRunningUnderARM64Translation, getElectronAppBasePath, getElectronAppUnpackedBasePath, getWaveConfigDir, @@ -588,6 +589,7 @@ async function appMain() { await electronApp.whenReady(); configureAuthKeyRequestInjection(electron.session.defaultSession); const fullConfig = await services.FileService.GetFullConfig(); + checkIfRunningUnderARM64Translation(fullConfig); ensureHotSpareTab(fullConfig); await relaunchBrowserWindows(); await initDocsite(); diff --git a/emain/platform.ts b/emain/platform.ts index 2bab197f6..8e9038918 100644 --- a/emain/platform.ts +++ b/emain/platform.ts @@ -1,7 +1,8 @@ // Copyright 2024, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -import { app, ipcMain } from "electron"; +import { fireAndForget } from "@/util/util"; +import { app, dialog, ipcMain, shell } from "electron"; import envPaths from "env-paths"; import { existsSync, mkdirSync } from "fs"; import os from "os"; @@ -40,6 +41,32 @@ const WaveConfigHomeVarName = "WAVETERM_CONFIG_HOME"; const WaveDataHomeVarName = "WAVETERM_DATA_HOME"; const WaveHomeVarName = "WAVETERM_HOME"; +export function checkIfRunningUnderARM64Translation(fullConfig: FullConfigType) { + if (!fullConfig.settings["app:dismissarchitecturewarning"] && app.runningUnderARM64Translation) { + console.log("Running under ARM64 translation, alerting user"); + const dialogOpts: Electron.MessageBoxOptions = { + type: "warning", + buttons: ["Dismiss", "Learn More"], + title: "Wave has detected a performance issue", + message: `Wave is running in ARM64 translation mode which may impact performance.\n\nRecommendation: Download the native ARM64 version from our website for optimal performance.`, + }; + + const choice = dialog.showMessageBoxSync(null, dialogOpts); + if (choice === 1) { + // Open the documentation URL + console.log("User chose to learn more"); + fireAndForget(() => + shell.openExternal( + "https://docs.waveterm.dev/faq#why-does-wave-warn-me-about-arm64-translation-when-it-launches" + ) + ); + throw new Error("User redirected to docsite to learn more about ARM64 translation, exiting"); + } else { + console.log("User dismissed the dialog"); + } + } +} + /** * Gets the path to the old Wave home directory (defaults to `~/.waveterm`). * @returns The path to the directory if it exists and contains valid data for the current app, otherwise null. diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index c0149d01e..831c9e734 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -618,6 +618,7 @@ declare global { type SettingsType = { "app:*"?: boolean; "app:globalhotkey"?: string; + "app:dismissarchitecturewarning"?: boolean; "ai:*"?: boolean; "ai:preset"?: string; "ai:apitype"?: string; diff --git a/pkg/wconfig/metaconsts.go b/pkg/wconfig/metaconsts.go index 7e95579ad..a1ddaeb4a 100644 --- a/pkg/wconfig/metaconsts.go +++ b/pkg/wconfig/metaconsts.go @@ -8,6 +8,7 @@ package wconfig const ( ConfigKey_AppClear = "app:*" ConfigKey_AppGlobalHotkey = "app:globalhotkey" + ConfigKey_AppDismissArchitectureWarning = "app:dismissarchitecturewarning" ConfigKey_AiClear = "ai:*" ConfigKey_AiPreset = "ai:preset" diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index 8b312db4b..b1461eb6f 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -33,8 +33,9 @@ const AnySchema = ` ` type SettingsType struct { - AppClear bool `json:"app:*,omitempty"` - AppGlobalHotkey string `json:"app:globalhotkey,omitempty"` + AppClear bool `json:"app:*,omitempty"` + AppGlobalHotkey string `json:"app:globalhotkey,omitempty"` + AppDismissArchitectureWarning bool `json:"app:dismissarchitecturewarning,omitempty"` AiClear bool `json:"ai:*,omitempty"` AiPreset string `json:"ai:preset,omitempty"` From 8ae6e47d9b66355022378f7c7c8a80341bffaa3a Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Thu, 19 Dec 2024 10:35:50 -0800 Subject: [PATCH 26/35] fix blockstore panic (#1570) --- pkg/filestore/blockstore_cache.go | 3 +++ pkg/wshutil/wshrpc.go | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/filestore/blockstore_cache.go b/pkg/filestore/blockstore_cache.go index f8608654b..ab48e7a83 100644 --- a/pkg/filestore/blockstore_cache.go +++ b/pkg/filestore/blockstore_cache.go @@ -227,6 +227,9 @@ func (entry *CacheEntry) readAt(ctx context.Context, offset int64, size int64, r offset += truncateAmt size -= truncateAmt } + if size <= 0 { + return realDataOffset, nil, nil + } } partMap := file.computePartMap(offset, size) dataEntryMap, err := entry.loadDataPartsForRead(ctx, getPartIdxsFromMap(partMap)) diff --git a/pkg/wshutil/wshrpc.go b/pkg/wshutil/wshrpc.go index 4bbbbd01e..24bb8d483 100644 --- a/pkg/wshutil/wshrpc.go +++ b/pkg/wshutil/wshrpc.go @@ -342,7 +342,10 @@ func (w *WshRpc) runServer() { continue } if msg.IsRpcRequest() { - go w.handleRequest(&msg) + go func() { + defer panichandler.PanicHandler("handleRequest:goroutine") + w.handleRequest(&msg) + }() } else { respCh := w.getResponseCh(msg.ResId) if respCh == nil { From eff12635d72452355801acd5165caaa955490e7b Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Thu, 19 Dec 2024 10:41:28 -0800 Subject: [PATCH 27/35] transparent terminal themes (#1561) --- docs/docs/config.mdx | 2 + docs/docs/keybindings.mdx | 8 +++ frontend/app/view/term/term.tsx | 59 +++++++++++++++- frontend/app/view/term/termtheme.ts | 3 +- frontend/app/view/term/termutil.ts | 22 +++++- frontend/types/gotypes.d.ts | 2 + pkg/waveobj/metaconsts.go | 1 + pkg/waveobj/wtypemeta.go | 1 + pkg/wconfig/defaultconfig/termthemes.json | 86 +++++++++++++++-------- pkg/wconfig/metaconsts.go | 1 + pkg/wconfig/settingsconfig.go | 1 + 11 files changed, 151 insertions(+), 35 deletions(-) diff --git a/docs/docs/config.mdx b/docs/docs/config.mdx index c97ef839b..b1c7b89c5 100644 --- a/docs/docs/config.mdx +++ b/docs/docs/config.mdx @@ -45,6 +45,8 @@ wsh editconfig | term:localshellopts | string[] | set to pass additional parameters to the term:localshellpath (example: `["-NoLogo"]` for PowerShell will remove the copyright notice) | | term:copyonselect | bool | set to false to disable terminal copy-on-select | | term:scrollback | int | size of terminal scrollback buffer, max is 10000 | +| term:theme | string | preset name of terminal theme to apply by default (default is "default-dark") | +| term:transparency | float64 | set the background transparency of terminal theme (default 0.5, 0 = not transparent, 1.0 = fully transparent) | | editor:minimapenabled | bool | set to false to disable editor minimap | | editor:stickyscrollenabled | bool | enables monaco editor's stickyScroll feature (pinning headers of current context, e.g. class names, method names, etc.), defaults to false | | editor:wordwrap | bool | set to true to enable word wrapping in the editor (defaults to false) | diff --git a/docs/docs/keybindings.mdx b/docs/docs/keybindings.mdx index cfb1569e5..7bd2775d6 100644 --- a/docs/docs/keybindings.mdx +++ b/docs/docs/keybindings.mdx @@ -71,6 +71,14 @@ replace "Cmd" with "Alt" (note that "Ctrl" is "Ctrl" on both Mac, Windows, and L | ---------------- | ------------- | | | Clear AI Chat | +## Terminal Keybindings + +| Key | Function | +| ----------------------- | -------------- | +| | Copy | +| | Paste | +| | Clear Terminal | + ## Customizeable Systemwide Global Hotkey Wave allows setting a custom global hotkey to focus your most recent window from anywhere in your computer. For more information on this, see [the config docs](./config#customizable-systemwide-global-hotkey). diff --git a/frontend/app/view/term/term.tsx b/frontend/app/view/term/term.tsx index a834adfd5..d6ad8eec9 100644 --- a/frontend/app/view/term/term.tsx +++ b/frontend/app/view/term/term.tsx @@ -24,6 +24,7 @@ import { } from "@/store/global"; import * as services from "@/store/services"; import * as keyutil from "@/util/keyutil"; +import { boundNumber } from "@/util/util"; import clsx from "clsx"; import debug from "debug"; import * as jotai from "jotai"; @@ -62,6 +63,7 @@ class TermViewModel implements ViewModel { vdomToolbarTarget: jotai.PrimitiveAtom; fontSizeAtom: jotai.Atom; termThemeNameAtom: jotai.Atom; + termTransparencyAtom: jotai.Atom; noPadding: jotai.PrimitiveAtom; endIconButtons: jotai.Atom; shellProcFullStatus: jotai.PrimitiveAtom; @@ -203,10 +205,17 @@ class TermViewModel implements ViewModel { return get(getOverrideConfigAtom(this.blockId, "term:theme")) ?? DefaultTermTheme; }); }); + this.termTransparencyAtom = useBlockAtom(blockId, "termtransparencyatom", () => { + return jotai.atom((get) => { + let value = get(getOverrideConfigAtom(this.blockId, "term:transparency")) ?? 0.5; + return boundNumber(value, 0, 1); + }); + }); this.blockBg = jotai.atom((get) => { const fullConfig = get(atoms.fullConfigAtom); const themeName = get(this.termThemeNameAtom); - const [_, bgcolor] = computeTheme(fullConfig, themeName); + const termTransparency = get(this.termTransparencyAtom); + const [_, bgcolor] = computeTheme(fullConfig, themeName, termTransparency); if (bgcolor != null) { return { bg: bgcolor }; } @@ -407,6 +416,11 @@ class TermViewModel implements ViewModel { event.preventDefault(); event.stopPropagation(); return false; + } else if (keyutil.checkKeyPressed(waveEvent, "Cmd:k")) { + event.preventDefault(); + event.stopPropagation(); + this.termRef.current?.terminal?.clear(); + return false; } const shellProcStatus = globalStore.get(this.shellProcStatus); if ((shellProcStatus == "done" || shellProcStatus == "init") && keyutil.checkKeyPressed(waveEvent, "Enter")) { @@ -453,6 +467,7 @@ class TermViewModel implements ViewModel { const termThemeKeys = Object.keys(termThemes); const curThemeName = globalStore.get(getBlockMetaKeyAtom(this.blockId, "term:theme")); const defaultFontSize = globalStore.get(getSettingsKeyAtom("term:fontsize")) ?? 12; + const transparencyMeta = globalStore.get(getBlockMetaKeyAtom(this.blockId, "term:transparency")); const blockData = globalStore.get(this.blockAtom); const overrideFontSize = blockData?.meta?.["term:fontsize"]; @@ -474,6 +489,41 @@ class TermViewModel implements ViewModel { checked: curThemeName == null, click: () => this.setTerminalTheme(null), }); + const transparencySubMenu: ContextMenuItem[] = []; + transparencySubMenu.push({ + label: "Default", + type: "checkbox", + checked: transparencyMeta == null, + click: () => { + RpcApi.SetMetaCommand(TabRpcClient, { + oref: WOS.makeORef("block", this.blockId), + meta: { "term:transparency": null }, + }); + }, + }); + transparencySubMenu.push({ + label: "Transparent Background", + type: "checkbox", + checked: transparencyMeta == 0.5, + click: () => { + RpcApi.SetMetaCommand(TabRpcClient, { + oref: WOS.makeORef("block", this.blockId), + meta: { "term:transparency": 0.5 }, + }); + }, + }); + transparencySubMenu.push({ + label: "No Transparency", + type: "checkbox", + checked: transparencyMeta == 0, + click: () => { + RpcApi.SetMetaCommand(TabRpcClient, { + oref: WOS.makeORef("block", this.blockId), + meta: { "term:transparency": 0 }, + }); + }, + }); + const fontSizeSubMenu: ContextMenuItem[] = [6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18].map( (fontSize: number) => { return { @@ -508,6 +558,10 @@ class TermViewModel implements ViewModel { label: "Font Size", submenu: fontSizeSubMenu, }); + fullMenu.push({ + label: "Transparency", + submenu: transparencySubMenu, + }); fullMenu.push({ type: "separator" }); fullMenu.push({ label: "Force Restart Controller", @@ -734,7 +788,8 @@ const TerminalView = ({ blockId, model }: TerminalViewProps) => { React.useEffect(() => { const fullConfig = globalStore.get(atoms.fullConfigAtom); const termThemeName = globalStore.get(model.termThemeNameAtom); - const [termTheme, _] = computeTheme(fullConfig, termThemeName); + const termTransparency = globalStore.get(model.termTransparencyAtom); + const [termTheme, _] = computeTheme(fullConfig, termThemeName, termTransparency); let termScrollback = 1000; if (termSettings?.["term:scrollback"]) { termScrollback = Math.floor(termSettings["term:scrollback"]); diff --git a/frontend/app/view/term/termtheme.ts b/frontend/app/view/term/termtheme.ts index 8852ae15a..32937b5be 100644 --- a/frontend/app/view/term/termtheme.ts +++ b/frontend/app/view/term/termtheme.ts @@ -17,7 +17,8 @@ interface TermThemeProps { const TermThemeUpdater = ({ blockId, model, termRef }: TermThemeProps) => { const fullConfig = useAtomValue(atoms.fullConfigAtom); const blockTermTheme = useAtomValue(model.termThemeNameAtom); - const [theme, _] = computeTheme(fullConfig, blockTermTheme); + const transparency = useAtomValue(model.termTransparencyAtom); + const [theme, _] = computeTheme(fullConfig, blockTermTheme, transparency); useEffect(() => { if (termRef.current?.terminal) { termRef.current.terminal.options.theme = theme; diff --git a/frontend/app/view/term/termutil.ts b/frontend/app/view/term/termutil.ts index 1bed0e6d5..6b2eb357c 100644 --- a/frontend/app/view/term/termutil.ts +++ b/frontend/app/view/term/termutil.ts @@ -2,14 +2,32 @@ // SPDX-License-Identifier: Apache-2.0 export const DefaultTermTheme = "default-dark"; +import { colord } from "colord"; -// returns (theme, bgcolor) -function computeTheme(fullConfig: FullConfigType, themeName: string): [TermThemeType, string] { +function applyTransparencyToColor(hexColor: string, transparency: number): string { + const alpha = 1 - transparency; // transparency is already 0-1 + return colord(hexColor).alpha(alpha).toHex(); +} + +// returns (theme, bgcolor, transparency (0 - 1.0)) +function computeTheme( + fullConfig: FullConfigType, + themeName: string, + termTransparency: number +): [TermThemeType, string] { let theme: TermThemeType = fullConfig?.termthemes?.[themeName]; if (theme == null) { theme = fullConfig?.termthemes?.[DefaultTermTheme] || ({} as any); } const themeCopy = { ...theme }; + if (termTransparency != null && termTransparency > 0) { + if (themeCopy.background) { + themeCopy.background = applyTransparencyToColor(themeCopy.background, termTransparency); + } + if (themeCopy.selectionBackground) { + themeCopy.selectionBackground = applyTransparencyToColor(themeCopy.selectionBackground, termTransparency); + } + } let bgcolor = themeCopy.background; themeCopy.background = "#00000000"; return [themeCopy, bgcolor]; diff --git a/frontend/types/gotypes.d.ts b/frontend/types/gotypes.d.ts index 831c9e734..15838e1ab 100644 --- a/frontend/types/gotypes.d.ts +++ b/frontend/types/gotypes.d.ts @@ -491,6 +491,7 @@ declare global { "term:scrollback"?: number; "term:vdomblockid"?: string; "term:vdomtoolbarblockid"?: string; + "term:transparency"?: number; "web:zoom"?: number; "markdown:fontsize"?: number; "markdown:fixedfontsize"?: number; @@ -641,6 +642,7 @@ declare global { "term:localshellopts"?: string[]; "term:scrollback"?: number; "term:copyonselect"?: boolean; + "term:transparency"?: number; "editor:minimapenabled"?: boolean; "editor:stickyscrollenabled"?: boolean; "editor:wordwrap"?: boolean; diff --git a/pkg/waveobj/metaconsts.go b/pkg/waveobj/metaconsts.go index 9071bf326..6b65249b6 100644 --- a/pkg/waveobj/metaconsts.go +++ b/pkg/waveobj/metaconsts.go @@ -93,6 +93,7 @@ const ( MetaKey_TermScrollback = "term:scrollback" MetaKey_TermVDomSubBlockId = "term:vdomblockid" MetaKey_TermVDomToolbarBlockId = "term:vdomtoolbarblockid" + MetaKey_TermTransparency = "term:transparency" MetaKey_WebZoom = "web:zoom" diff --git a/pkg/waveobj/wtypemeta.go b/pkg/waveobj/wtypemeta.go index 41f0b7be5..bbf30cffb 100644 --- a/pkg/waveobj/wtypemeta.go +++ b/pkg/waveobj/wtypemeta.go @@ -94,6 +94,7 @@ type MetaTSType struct { TermScrollback *int `json:"term:scrollback,omitempty"` TermVDomSubBlockId string `json:"term:vdomblockid,omitempty"` TermVDomToolbarBlockId string `json:"term:vdomtoolbarblockid,omitempty"` + TermTransparency *float64 `json:"term:transparency,omitempty"` // default 0.5 WebZoom float64 `json:"web:zoom,omitempty"` diff --git a/pkg/wconfig/defaultconfig/termthemes.json b/pkg/wconfig/defaultconfig/termthemes.json index ea8a5f1a0..6ac212f31 100644 --- a/pkg/wconfig/defaultconfig/termthemes.json +++ b/pkg/wconfig/defaultconfig/termthemes.json @@ -22,12 +22,38 @@ "cmdtext": "#f0f0f0", "foreground": "#c1c1c1", "selectionBackground": "", - "background": "#00000077", + "background": "#000000", "cursor": "" }, + "onedarkpro": { + "display:name": "One Dark Pro", + "display:order": 2, + "background": "#282C34", + "foreground": "#ABB2BF", + "cursor": "#D7DAE0", + "selectionBackground": "#528BFF", + "black": "#3F4451", + "red": "#E05561", + "green": "#8CC265", + "yellow": "#D18F52", + "blue": "#4AA5F0", + "magenta": "#C162DE", + "cyan": "#42B3C2", + "white": "#D7DAE0", + "brightBlack": "#4F5666", + "brightRed": "#FF616E", + "brightGreen": "#A5E075", + "brightYellow": "#F0A45D", + "brightBlue": "#4DC4FF", + "brightMagenta": "#DE73FF", + "brightCyan": "#4CD1E0", + "brightWhite": "#E6E6E6", + "gray": "#495162", + "cmdtext": "#ABB2BF" + }, "dracula": { "display:name": "Dracula", - "display:order": 2, + "display:order": 3, "black": "#21222C", "red": "#FF5555", "green": "#50FA7B", @@ -53,7 +79,7 @@ }, "monokai": { "display:name": "Monokai", - "display:order": 3, + "display:order": 4, "black": "#1B1D1E", "red": "#F92672", "green": "#A6E22E", @@ -79,7 +105,7 @@ }, "campbell": { "display:name": "Campbell", - "display:order": 4, + "display:order": 5, "black": "#0C0C0C", "red": "#C50F1F", "green": "#13A10E", @@ -105,7 +131,7 @@ }, "warmyellow": { "display:name": "Warm Yellow", - "display:order": 4, + "display:order": 6, "black": "#3C3228", "red": "#E67E22", "green": "#A5D6A7", @@ -127,30 +153,30 @@ "selectionBackground": "#B7950B", "cursor": "#F9D784" }, - "onedarkpro": { - "display:name": "One Dark Pro", - "display:order": 1.5, - "background": "#282C34", - "foreground": "#ABB2BF", - "cursor": "#D7DAE0", - "selectionBackground": "#528BFF", - "black": "#3F4451", - "red": "#E05561", - "green": "#8CC265", - "yellow": "#D18F52", - "blue": "#4AA5F0", - "magenta": "#C162DE", - "cyan": "#42B3C2", - "white": "#D7DAE0", - "brightBlack": "#4F5666", - "brightRed": "#FF616E", - "brightGreen": "#A5E075", - "brightYellow": "#F0A45D", - "brightBlue": "#4DC4FF", - "brightMagenta": "#DE73FF", - "brightCyan": "#4CD1E0", - "brightWhite": "#E6E6E6", - "gray": "#495162", - "cmdtext": "#ABB2BF" + "rosepine": { + "display:name": "Rose Pine", + "display:order": 7, + "black": "#26233a", + "red": "#eb6f92", + "green": "#3e8fb0", + "yellow": "#f6c177", + "blue": "#9ccfd8", + "magenta": "#c4a7e7", + "cyan": "#ebbcba", + "white": "#e0def4", + "brightBlack": "#908caa", + "brightRed": "#ff8cab", + "brightGreen": "#9ccfb0", + "brightYellow": "#ffd196", + "brightBlue": "#bee6e0", + "brightMagenta": "#e2c4ff", + "brightCyan": "#ffd1d0", + "brightWhite": "#fffaf3", + "gray": "#908caa", + "cmdtext": "#e0def4", + "foreground": "#e0def4", + "selectionBackground": "#403d52", + "background": "#191724", + "cursor": "#524f67" } } diff --git a/pkg/wconfig/metaconsts.go b/pkg/wconfig/metaconsts.go index a1ddaeb4a..3197b9ad0 100644 --- a/pkg/wconfig/metaconsts.go +++ b/pkg/wconfig/metaconsts.go @@ -33,6 +33,7 @@ const ( ConfigKey_TermLocalShellOpts = "term:localshellopts" ConfigKey_TermScrollback = "term:scrollback" ConfigKey_TermCopyOnSelect = "term:copyonselect" + ConfigKey_TermTransparency = "term:transparency" ConfigKey_EditorMinimapEnabled = "editor:minimapenabled" ConfigKey_EditorStickyScrollEnabled = "editor:stickyscrollenabled" diff --git a/pkg/wconfig/settingsconfig.go b/pkg/wconfig/settingsconfig.go index b1461eb6f..b65a73a05 100644 --- a/pkg/wconfig/settingsconfig.go +++ b/pkg/wconfig/settingsconfig.go @@ -60,6 +60,7 @@ type SettingsType struct { TermLocalShellOpts []string `json:"term:localshellopts,omitempty"` TermScrollback *int64 `json:"term:scrollback,omitempty"` TermCopyOnSelect *bool `json:"term:copyonselect,omitempty"` + TermTransparency *float64 `json:"term:transparency,omitempty"` EditorMinimapEnabled bool `json:"editor:minimapenabled,omitempty"` EditorStickyScrollEnabled bool `json:"editor:stickyscrollenabled,omitempty"` From f12a2266b583681bc27118be2abc840e821eb4fe Mon Sep 17 00:00:00 2001 From: "wave-builder[bot]" <181805596+wave-builder[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 18:46:45 +0000 Subject: [PATCH 28/35] chore: bump package version to 0.10.2-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6497727ea..97254ed47 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "productName": "Wave", "description": "Open-Source AI-Native Terminal Built for Seamless Workflows", "license": "Apache-2.0", - "version": "0.10.2-beta.0", + "version": "0.10.2-beta.1", "homepage": "https://waveterm.dev", "build": { "appId": "dev.commandline.waveterm" From 2e2a6491e88438eacab313a5c3bd524fff199791 Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Thu, 19 Dec 2024 11:46:35 -0800 Subject: [PATCH 29/35] SSH Config Panic Handler (#1571) Match statements in files that are included in an ssh config still seem to cause panics with the ssh_config library. This adds a panic handler to catch them, and prevent the app from crashing. It does not resolve the underlying issue which will need to be done later. --- pkg/remote/sshclient.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/remote/sshclient.go b/pkg/remote/sshclient.go index bcc4291c2..3b2b0cc90 100644 --- a/pkg/remote/sshclient.go +++ b/pkg/remote/sshclient.go @@ -23,6 +23,7 @@ import ( "github.com/kevinburke/ssh_config" "github.com/skeema/knownhosts" + "github.com/wavetermdev/waveterm/pkg/panichandler" "github.com/wavetermdev/waveterm/pkg/trimquotes" "github.com/wavetermdev/waveterm/pkg/userinput" "github.com/wavetermdev/waveterm/pkg/util/shellutil" @@ -750,7 +751,13 @@ func combineSshKeywords(userProvidedOpts *wshrpc.ConnKeywords, configKeywords *w // note that a `var == "yes"` will default to false // but `var != "no"` will default to true // when given unexpected strings -func findSshConfigKeywords(hostPattern string) (*wshrpc.ConnKeywords, error) { +func findSshConfigKeywords(hostPattern string) (connKeywords *wshrpc.ConnKeywords, outErr error) { + defer func() { + err := panichandler.PanicHandler("sshclient:find-ssh-config-keywords") + if err != nil { + outErr = err + } + }() WaveSshConfigUserSettings().ReloadConfigs() sshKeywords := &wshrpc.ConnKeywords{} var err error From 12d58c90a74b6f255bbb7aad839b6d9e43c0e15f Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Thu, 19 Dec 2024 12:16:03 -0800 Subject: [PATCH 30/35] Make TOS modal buttons larger (#1573) --- frontend/app/modals/tos.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/app/modals/tos.scss b/frontend/app/modals/tos.scss index 72d8015af..1db743d36 100644 --- a/frontend/app/modals/tos.scss +++ b/frontend/app/modals/tos.scss @@ -230,6 +230,7 @@ justify-content: center; button { + padding: 8px 20px; font-size: 14px; } From 8a22149f2f12a667954bd6b7b0f27e4325cb934f Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Thu, 19 Dec 2024 12:41:03 -0800 Subject: [PATCH 31/35] fix markdown last margin (#1575) --- frontend/app/element/markdown.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/app/element/markdown.scss b/frontend/app/element/markdown.scss index 4bee56855..b49cdccfd 100644 --- a/frontend/app/element/markdown.scss +++ b/frontend/app/element/markdown.scss @@ -24,6 +24,10 @@ overflow: hidden; } + *:last-child { + margin-bottom: 0 !important; + } + .heading:not(.heading ~ .heading) { margin-top: 0 !important; } From 76e8bc4bae6f8dd146e92e608449005b34f98d9d Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:43:22 -0800 Subject: [PATCH 32/35] fix: unquote zdotdir for starting zsh in wsl (#1574) Due to the way this command is run, the quotes are not being handled by the shell. Removing them allows them to be interpreted correctly in most cases. This resolves #1569 --- pkg/shellexec/shellexec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/shellexec/shellexec.go b/pkg/shellexec/shellexec.go index 2c811d85c..a6fcf00e4 100644 --- a/pkg/shellexec/shellexec.go +++ b/pkg/shellexec/shellexec.go @@ -215,7 +215,7 @@ func StartWslShellProc(ctx context.Context, termSize waveobj.TermSize, cmdStr st } if isZshShell(shellPath) { - shellOpts = append(shellOpts, fmt.Sprintf(`ZDOTDIR="%s/.waveterm/%s"`, homeDir, shellutil.ZshIntegrationDir)) + shellOpts = append(shellOpts, fmt.Sprintf(`ZDOTDIR=%s/.waveterm/%s`, homeDir, shellutil.ZshIntegrationDir)) } shellOpts = append(shellOpts, shellPath) shellOpts = append(shellOpts, subShellOpts...) From a940de6df6b3175e88d65379fe4f7b093a63f199 Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:55:36 -0800 Subject: [PATCH 33/35] fix: use updates ssh_config version with match fix (#1576) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 772c34c62..aa784a472 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,6 @@ require ( golang.org/x/net v0.29.0 // indirect ) -replace github.com/kevinburke/ssh_config => github.com/wavetermdev/ssh_config v0.0.0-20241027232332-ed124367682d +replace github.com/kevinburke/ssh_config => github.com/wavetermdev/ssh_config v0.0.0-20241219203747-6409e4292f34 replace github.com/creack/pty => github.com/photostorm/pty v1.1.19-0.20230903182454-31354506054b diff --git a/go.sum b/go.sum index 8429144ec..437167932 100644 --- a/go.sum +++ b/go.sum @@ -90,8 +90,8 @@ github.com/ubuntu/gowsl v0.0.0-20240906163211-049fd49bd93b h1:wFBKF5k5xbJQU8bYgc github.com/ubuntu/gowsl v0.0.0-20240906163211-049fd49bd93b/go.mod h1:N1CYNinssZru+ikvYTgVbVeSi21thHUTCoJ9xMvWe+s= github.com/wavetermdev/htmltoken v0.2.0 h1:sFVPPemlDv7/jg7n4Hx1AEF2m9MVAFjFpELWfhi/DlM= github.com/wavetermdev/htmltoken v0.2.0/go.mod h1:5FM0XV6zNYiNza2iaTcFGj+hnMtgqumFHO31Z8euquk= -github.com/wavetermdev/ssh_config v0.0.0-20241027232332-ed124367682d h1:ArHaUBaiQWUqBzM2G/oLlm3Be0kwUMDt9vTNOWIfOd0= -github.com/wavetermdev/ssh_config v0.0.0-20241027232332-ed124367682d/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= +github.com/wavetermdev/ssh_config v0.0.0-20241219203747-6409e4292f34 h1:I8VZVTZEXhnzfN7jB9a7TZYpzNO48sCUWMRXHM9XWSA= +github.com/wavetermdev/ssh_config v0.0.0-20241219203747-6409e4292f34/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= From 0f15e4ff56b88a788a0a9ee5af0aaf0547176374 Mon Sep 17 00:00:00 2001 From: Sylvie Crowe <107814465+oneirocosm@users.noreply.github.com> Date: Thu, 19 Dec 2024 13:01:12 -0800 Subject: [PATCH 34/35] fix: bound custom fontsizes between 6 and 64 (#1577) Adds bounding for markdown (and AI) fontsize and fixedfontsize. --- frontend/app/element/markdown.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/app/element/markdown.tsx b/frontend/app/element/markdown.tsx index 5e6f596cf..a59fa877a 100644 --- a/frontend/app/element/markdown.tsx +++ b/frontend/app/element/markdown.tsx @@ -9,7 +9,7 @@ import { resolveSrcSet, transformBlocks, } from "@/app/element/markdown-util"; -import { useAtomValueSafe } from "@/util/util"; +import { boundNumber, useAtomValueSafe } from "@/util/util"; import { clsx } from "clsx"; import { Atom } from "jotai"; import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react"; @@ -380,10 +380,10 @@ const Markdown = ({ const mergedStyle = { ...style }; if (fontSizeOverride != null) { - mergedStyle["--markdown-font-size"] = `${fontSizeOverride}px`; + mergedStyle["--markdown-font-size"] = `${boundNumber(fontSizeOverride, 6, 64)}px`; } if (fixedFontSizeOverride != null) { - mergedStyle["--markdown-fixed-font-size"] = `${fixedFontSizeOverride}px`; + mergedStyle["--markdown-fixed-font-size"] = `${boundNumber(fixedFontSizeOverride, 6, 64)}px`; } return (
From 8235f34921525568688059cc20b99d1af7c0f924 Mon Sep 17 00:00:00 2001 From: "wave-builder[bot]" <181805596+wave-builder[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:23:37 +0000 Subject: [PATCH 35/35] chore: bump package version to 0.10.2-beta.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 97254ed47..6c24ec9c4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "productName": "Wave", "description": "Open-Source AI-Native Terminal Built for Seamless Workflows", "license": "Apache-2.0", - "version": "0.10.2-beta.1", + "version": "0.10.2-beta.2", "homepage": "https://waveterm.dev", "build": { "appId": "dev.commandline.waveterm"