From a7641e5e90bac3275dfa8891d195078e0da83c2c Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 9 Oct 2025 13:07:13 -0700 Subject: [PATCH 01/10] update waveai max width, set default to closed, migrate quicktips to tailwind, add Wave AI keybindings to quick tips. update starter layout, integrate wave ai. --- frontend/app/element/quicktips.scss | 85 ---------------- frontend/app/element/quicktips.tsx | 97 ++++++++++--------- .../app/workspace/workspace-layout-model.ts | 4 +- frontend/tailwindsetup.css | 1 + pkg/wcore/layout.go | 22 ----- pkg/wcore/workspace.go | 11 ++- 6 files changed, 64 insertions(+), 156 deletions(-) delete mode 100644 frontend/app/element/quicktips.scss diff --git a/frontend/app/element/quicktips.scss b/frontend/app/element/quicktips.scss deleted file mode 100644 index db9692036b..0000000000 --- a/frontend/app/element/quicktips.scss +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2024, Command Line Inc. -// SPDX-License-Identifier: Apache-2.0 - -.tips-wrapper { - display: flex; - flex-direction: row; - width: 100%; - - .tips-section { - display: flex; - flex-direction: column; - flex-grow: 1; - gap: 5px; - - .tip-section-header { - font-weight: bold; - margin-bottom: 5px; - margin-top: 10px; - font-size: 16px; - - &:first-child { - margin-top: 0; - } - } - - .tip { - display: flex; - flex-direction: row; - align-items: center; - - code { - padding: 0.1em 0.4em; - background-color: var(--highlight-bg-color); - } - - .keybinding-group { - display: flex; - flex-direction: row; - align-items: center; - margin-left: 5px; - margin-right: 5px; - align-self: flex-start; - - &:first-child { - margin-left: 0; - } - } - - .keybinding { - display: inline-block; - padding: 0.1em 0.4em; - margin: 0 0.1em; - font: var(--fixed-font); - font-size: 0.85em; - color: var(--keybinding-color); - background-color: var(--highlight-bg-color); - border-radius: 4px; - border: 1px solid var(--keybinding-border-color); - box-shadow: none; - white-space: nowrap; - } - - .icon-wrap { - background-color: var(--highlight-bg-color); - padding: 2px; - color: var(--secondary-text-color); - font-size: 12px; - border-radius: 2px; - margin-right: 5px; - align-self: flex-start; - - svg { - position: relative; - top: 3px; - left: 1px; - height: 13px; - #arrow1, - #arrow2 { - fill: var(--main-text-color); - } - } - } - } - } -} diff --git a/frontend/app/element/quicktips.tsx b/frontend/app/element/quicktips.tsx index 36243b8b00..6bbb883fba 100644 --- a/frontend/app/element/quicktips.tsx +++ b/frontend/app/element/quicktips.tsx @@ -3,7 +3,6 @@ import { MagnifyIcon } from "@/app/element/magnify"; import { PLATFORM, PlatformMacOS } from "@/util/platformutil"; -import "./quicktips.scss"; const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { const parts = keyDecl.split(":"); @@ -12,13 +11,13 @@ const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { if (part === "Cmd") { if (PLATFORM === PlatformMacOS) { elems.push( -
+
⌘ Cmd
); } else { elems.push( -
+
Alt
); @@ -27,7 +26,7 @@ const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { } if (part == "Ctrl") { elems.push( -
+
^ Ctrl
); @@ -35,7 +34,7 @@ const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { } if (part == "Shift") { elems.push( -
+
⇧ Shift
); @@ -43,22 +42,22 @@ const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { } if (part == "Arrows") { elems.push( -
+
); elems.push( -
+
); elems.push( -
+
); elems.push( -
+
); @@ -66,107 +65,115 @@ const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { } if (part == "Digit") { elems.push( -
+
Number (1-9)
); continue; } elems.push( -
+
{part.toUpperCase()}
); } - return
{elems}
; + return
{elems}
; }; const QuickTips = () => { return ( -
-
-
Header Icons
-
-
+
+
+
Header Icons
+
+
Connect to a remote server
-
-
+
+
Magnify a Block
-
-
+
+
Block Settings
-
-
+
+
Close Block
-
Important Keybindings
+
Important Keybindings
-
+
New Tab
-
+
New Terminal Block
-
+
Navigate Between Blocks
-
+
Focus Nth Block
-
+
Switch To Nth Tab
+
+ + Open Wave AI Panel +
+
+ + Focus Wave AI +
-
wsh commands
-
+
wsh commands
+
- wsh view [filename|url] -
+ wsh view [filename|url] +
Run this command in the terminal to preview a file, directory, or web URL.
-
More Tips
-
-
+
More Tips
+
+
Right click the tabs to change backgrounds or rename.
-
-
+
+
Click the gear in the web view to set your homepage
-
-
+
+
Click the gear in the terminal to set your terminal theme and font size
-
Need More Help?
-
-
+
Need More Help?
+
+
@@ -175,8 +182,8 @@ const QuickTips = () => {
-
-
+
+
diff --git a/frontend/app/workspace/workspace-layout-model.ts b/frontend/app/workspace/workspace-layout-model.ts index f2a429efd2..da1ffa4a1c 100644 --- a/frontend/app/workspace/workspace-layout-model.ts +++ b/frontend/app/workspace/workspace-layout-model.ts @@ -18,7 +18,7 @@ const dlog = debug("wave:workspace"); const AIPANEL_DEFAULTWIDTH = 300; const AIPANEL_DEFAULTWIDTHRATIO = 0.33; const AIPANEL_MINWIDTH = 300; -const AIPANEL_MAXWIDTHRATIO = 0.5; +const AIPANEL_MAXWIDTHRATIO = 0.66; class WorkspaceLayoutModel { private static instance: WorkspaceLayoutModel | null = null; @@ -42,7 +42,7 @@ class WorkspaceLayoutModel { this.panelContainerRef = null; this.aiPanelWrapperRef = null; this.inResize = false; - this.aiPanelVisible = true; + this.aiPanelVisible = false; this.aiPanelWidth = null; this.panelVisibleAtom = jotai.atom(this.aiPanelVisible); diff --git a/frontend/tailwindsetup.css b/frontend/tailwindsetup.css index 7f43b55ec7..858c7cde05 100644 --- a/frontend/tailwindsetup.css +++ b/frontend/tailwindsetup.css @@ -31,6 +31,7 @@ --color-modalbg: #232323; --color-accentbg: rgba(88, 193, 66, 0.5); --color-hoverbg: rgba(255, 255, 255, 0.2); + --color-highlightbg: rgba(255, 255, 255, 0.2); --color-accent: rgb(88, 193, 66); --color-accenthover: rgb(118, 223, 96); diff --git a/pkg/wcore/layout.go b/pkg/wcore/layout.go index 9ddbe593eb..6a5b7c22f6 100644 --- a/pkg/wcore/layout.go +++ b/pkg/wcore/layout.go @@ -56,27 +56,6 @@ func GetStarterLayout() PortableLayout { waveobj.MetaKey_File: "~", }, }}, - {IndexArr: []int{2}, BlockDef: &waveobj.BlockDef{ - Meta: waveobj.MetaMapType{ - waveobj.MetaKey_View: "tips", - }, - }}, - {IndexArr: []int{2, 1}, BlockDef: &waveobj.BlockDef{ - Meta: waveobj.MetaMapType{ - waveobj.MetaKey_View: "help", - }, - }}, - {IndexArr: []int{2, 2}, BlockDef: &waveobj.BlockDef{ - Meta: waveobj.MetaMapType{ - waveobj.MetaKey_View: "waveai", - }, - }}, - // {IndexArr: []int{2, 2}, BlockDef: &wstore.BlockDef{ - // Meta: wstore.MetaMapType{ - // waveobj.MetaKey_View: "web", - // waveobj.MetaKey_Url: "https://www.youtube.com/embed/cKqsw_sAsU8", - // }, - // }}, } } @@ -189,7 +168,6 @@ func BootstrapStarterLayout(ctx context.Context) error { tabId := workspace.ActiveTabId starterLayout := GetStarterLayout() - err = ApplyPortableLayout(ctx, tabId, starterLayout, false) if err != nil { return fmt.Errorf("error applying starter layout: %w", err) diff --git a/pkg/wcore/workspace.go b/pkg/wcore/workspace.go index 14f63b9523..6f4253316b 100644 --- a/pkg/wcore/workspace.go +++ b/pkg/wcore/workspace.go @@ -208,7 +208,13 @@ func CreateTab(ctx context.Context, workspaceId string, tabName string, activate } // The initial tab for the initial launch should be pinned - tab, err := createTabObj(ctx, workspaceId, tabName, pinned || isInitialLaunch) + var meta waveobj.MetaMapType + if isInitialLaunch { + meta = waveobj.MetaMapType{ + "waveai:panelopen": true, + } + } + tab, err := createTabObj(ctx, workspaceId, tabName, pinned || isInitialLaunch, meta) if err != nil { return "", fmt.Errorf("error creating tab: %w", err) } @@ -240,7 +246,7 @@ func CreateTab(ctx context.Context, workspaceId string, tabName string, activate return tab.OID, nil } -func createTabObj(ctx context.Context, workspaceId string, name string, pinned bool) (*waveobj.Tab, error) { +func createTabObj(ctx context.Context, workspaceId string, name string, pinned bool, meta waveobj.MetaMapType) (*waveobj.Tab, error) { ws, err := GetWorkspace(ctx, workspaceId) if err != nil { return nil, fmt.Errorf("workspace %s not found: %w", workspaceId, err) @@ -251,6 +257,7 @@ func createTabObj(ctx context.Context, workspaceId string, name string, pinned b Name: name, BlockIds: []string{}, LayoutState: layoutStateId, + Meta: meta, } layoutState := &waveobj.LayoutState{ OID: layoutStateId, From ac013f12ad6d07e6cdfb6dbd0b0878ca1cfb7ad7 Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 9 Oct 2025 13:10:01 -0700 Subject: [PATCH 02/10] encapsulate a bit better --- frontend/app/element/quicktips.tsx | 112 ++++++++++++----------------- 1 file changed, 44 insertions(+), 68 deletions(-) diff --git a/frontend/app/element/quicktips.tsx b/frontend/app/element/quicktips.tsx index 6bbb883fba..1f6168a085 100644 --- a/frontend/app/element/quicktips.tsx +++ b/frontend/app/element/quicktips.tsx @@ -4,78 +4,54 @@ import { MagnifyIcon } from "@/app/element/magnify"; import { PLATFORM, PlatformMacOS } from "@/util/platformutil"; +const KeyCap = ({ children }: { children: React.ReactNode }) => { + return ( +
+ {children} +
+ ); +}; + +const IconBox = ({ children }: { children: React.ReactNode }) => { + return ( +
+ {children} +
+ ); +}; + const KeyBinding = ({ keyDecl }: { keyDecl: string }) => { const parts = keyDecl.split(":"); const elems: React.ReactNode[] = []; for (let part of parts) { if (part === "Cmd") { if (PLATFORM === PlatformMacOS) { - elems.push( -
- ⌘ Cmd -
- ); + elems.push(⌘ Cmd); } else { - elems.push( -
- Alt -
- ); + elems.push(Alt); } continue; } if (part == "Ctrl") { - elems.push( -
- ^ Ctrl -
- ); + elems.push(^ Ctrl); continue; } if (part == "Shift") { - elems.push( -
- ⇧ Shift -
- ); + elems.push(⇧ Shift); continue; } if (part == "Arrows") { - elems.push( -
- ← -
- ); - elems.push( -
- → -
- ); - elems.push( -
- ↑ -
- ); - elems.push( -
- ↓ -
- ); + elems.push(); + elems.push(); + elems.push(); + elems.push(); continue; } if (part == "Digit") { - elems.push( -
- Number (1-9) -
- ); + elems.push(Number (1-9)); continue; } - elems.push( -
- {part.toUpperCase()} -
- ); + elems.push({part.toUpperCase()}); } return
{elems}
; }; @@ -86,28 +62,28 @@ const QuickTips = () => {
Header Icons
-
+ -
+ Connect to a remote server
-
+ -
+ Magnify a Block
-
+ -
+ Block Settings
-
+ -
+ Close Block
@@ -154,28 +130,28 @@ const QuickTips = () => {
More Tips
-
+ -
+ Right click the tabs to change backgrounds or rename.
-
+ -
+ Click the gear in the web view to set your homepage
-
+ -
+ Click the gear in the terminal to set your terminal theme and font size
Need More Help?
-
+ -
+
Configuration Options From 1793acebb8a464709f4f24caa9d2c211ff41d0cb Mon Sep 17 00:00:00 2001 From: sawka Date: Thu, 9 Oct 2025 13:17:12 -0700 Subject: [PATCH 03/10] fix scroll behavior on quicktips in TOS modal --- frontend/app/modals/tos.tsx | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/frontend/app/modals/tos.tsx b/frontend/app/modals/tos.tsx index 572cba03ae..d9240d27a8 100644 --- a/frontend/app/modals/tos.tsx +++ b/frontend/app/modals/tos.tsx @@ -129,24 +129,29 @@ const ModalPage2 = () => { }; return ( - <> -
+
+
Icons and Keybindings
-
- -
-
+ +
+ +
+
+
- +
); }; @@ -199,6 +204,17 @@ const TosModal = () => { if (pageComp == null) { return null; } + + if (pageNum === 2) { + return ( + +
+ {pageComp} +
+
+ ); + } + return ( Date: Thu, 9 Oct 2025 14:24:47 -0700 Subject: [PATCH 04/10] better onboarding TOS screens when smaller vertical space --- emain/emain-window.ts | 4 +- frontend/app/modals/modal.scss | 1 - frontend/app/modals/modal.tsx | 3 +- frontend/app/modals/tos.tsx | 166 ++++++++++++++++----------------- 4 files changed, 85 insertions(+), 89 deletions(-) diff --git a/emain/emain-window.ts b/emain/emain-window.ts index c008e6d370..4ceb6782d4 100644 --- a/emain/emain-window.ts +++ b/emain/emain-window.ts @@ -26,8 +26,8 @@ export type WindowOpts = { unamePlatform: string; }; -const MIN_WINDOW_WIDTH = 600; -const MIN_WINDOW_HEIGHT = 350; +const MIN_WINDOW_WIDTH = 800; +const MIN_WINDOW_HEIGHT = 500; export const waveWindowMap = new Map(); // waveWindowId -> WaveBrowserWindow diff --git a/frontend/app/modals/modal.scss b/frontend/app/modals/modal.scss index c9f96a94a5..4471ca5d9a 100644 --- a/frontend/app/modals/modal.scss +++ b/frontend/app/modals/modal.scss @@ -29,7 +29,6 @@ display: flex; flex-direction: column; align-items: flex-start; - padding: 24px 16px 16px; border-radius: 8px; border: 0.5px solid var(--modal-border-color); background: var(--modal-bg-color); diff --git a/frontend/app/modals/modal.tsx b/frontend/app/modals/modal.tsx index 745283ab4b..c51e84ea0d 100644 --- a/frontend/app/modals/modal.tsx +++ b/frontend/app/modals/modal.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { Button } from "@/app/element/button"; +import { cn } from "@/util/util"; import clsx from "clsx"; import { forwardRef } from "react"; import ReactDOM from "react-dom"; @@ -95,7 +96,7 @@ const FlexiModal = forwardRef( const renderModal = () => (
{renderBackdrop(onClickBackdrop)} -
+
{children}
diff --git a/frontend/app/modals/tos.tsx b/frontend/app/modals/tos.tsx index d9240d27a8..90eed39297 100644 --- a/frontend/app/modals/tos.tsx +++ b/frontend/app/modals/tos.tsx @@ -10,14 +10,14 @@ import { useEffect, useRef, useState } from "react"; import { FlexiModal } from "./modal"; import { QuickTips } from "@/app/element/quicktips"; -import { atoms, getApi } from "@/app/store/global"; +import { atoms } from "@/app/store/global"; import { modalsModel } from "@/app/store/modalmodel"; import { fireAndForget } from "@/util/util"; import { atom, PrimitiveAtom, useAtom, useAtomValue, useSetAtom } from "jotai"; const pageNumAtom: PrimitiveAtom = atom(1); -const ModalPage1 = () => { +const ModalPage1 = ({ isCompact }: { isCompact: boolean }) => { const settings = useAtomValue(atoms.settingsAtom); const clientData = useAtomValue(atoms.client); const [telemetryEnabled, setTelemetryEnabled] = useState(!!settings["telemetry:enabled"]); @@ -41,87 +41,94 @@ const ModalPage1 = () => { const label = telemetryEnabled ? "Telemetry Enabled" : "Telemetry Disabled"; return ( - <> -
-
+
+
+
Welcome to Wave Terminal
-
-
- -
-
Support us on GitHub
-
- We're open source and committed to providing a free terminal for individual users. - Please show your support by giving us a star on{" "} + +
+
+ +
+
Support us on GitHub
+
+ We're open source and committed to providing a free terminal for individual + users. Please show your support by giving us a star on{" "} + + Github (wavetermdev/waveterm) + +
+
-
-
-
- - - -
-
-
Join our Community
-
- Get help, submit feature requests, report bugs, or just chat with fellow terminal - enthusiasts. -
+
+ +
+
Join our Community
+
+ Get help, submit feature requests, report bugs, or just chat with fellow terminal + enthusiasts. +
+ + Join the Wave Discord Channel + +
+
-
-
-
- -
-
-
Telemetry
-
- We collect minimal anonymous{" "} - - telemetry data - {" "} - to help us understand how people are using Wave ( - - Privacy Policy - - ). +
+
+ +
+
+
Telemetry
+
+ We collect minimal anonymous{" "} + + telemetry data + {" "} + to help us understand how people are using Wave ( + + Privacy Policy + + ). +
+
-
-
-
+ +
- +
); }; -const ModalPage2 = () => { +const ModalPage2 = ({ isCompact }: { isCompact: boolean }) => { const [tosOpen, setTosOpen] = useAtom(modalsModel.tosOpen); const handleGetStarted = () => { @@ -130,8 +137,10 @@ const ModalPage2 = () => { return (
-
-
+
+
Icons and Keybindings
@@ -144,7 +153,7 @@ const ModalPage2 = () => {
-