Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,7 @@ tasks:
- mkdir -p scaffold
- cp ../templates/package.json.tmpl scaffold/package.json
- cd scaffold && npm install
- mv scaffold/node_modules scaffold/nm
- cp -r dist scaffold/
- mkdir -p scaffold/dist/tw
- cp ../templates/app-main.go.tmpl scaffold/app-main.go
Expand All @@ -556,6 +557,7 @@ tasks:
- powershell New-Item -ItemType Directory -Force -Path scaffold
- powershell Copy-Item -Path ../templates/package.json.tmpl -Destination scaffold/package.json
- powershell -Command "Set-Location scaffold; npm install"
- powershell Move-Item -Path scaffold/node_modules -Destination scaffold/nm
- powershell Copy-Item -Recurse -Force -Path dist -Destination scaffold/
- powershell New-Item -ItemType Directory -Force -Path scaffold/dist/tw
- powershell Copy-Item -Path ../templates/app-main.go.tmpl -Destination scaffold/app-main.go
Expand Down
1 change: 1 addition & 0 deletions docs/docs/releasenotes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Patch release with Wave AI model upgrade, new secret management features, and im

**Wave AI Updates:**
- **GPT-5.1 Model** - Upgraded to use OpenAI's GPT-5.1 model for improved responses
- **Thinking Mode Toggle** - New dropdown to select between Quick, Balanced, and Deep thinking modes for optimal response quality vs speed
- [bugfix] Fixed path mismatch issue when restoring AI write file backups

**New Features:**
Expand Down
9 changes: 7 additions & 2 deletions electron-builder.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const config = {
{
from: "./dist",
to: "./dist",
filter: ["**/*", "!bin/*", "bin/wavesrv.${arch}*", "bin/wsh*"],
filter: ["**/*", "!bin/*", "bin/wavesrv.${arch}*", "bin/wsh*", "!tsunamiscaffold/**/*"],
},
{
from: ".",
Expand All @@ -31,13 +31,18 @@ const config = {
},
"!node_modules", // We don't need electron-builder to package in Node modules as Vite has already bundled any code that our program is using.
],
extraResources: [
{
from: "dist/tsunamiscaffold",
to: "tsunamiscaffold",
},
],
directories: {
output: "make",
},
asarUnpack: [
"dist/bin/**/*", // wavesrv and wsh binaries
"dist/schema/**/*", // schema files for Monaco editor
"dist/tsunamiscaffold/**/*", // tsunami scaffold files
],
mac: {
target: [
Expand Down
12 changes: 7 additions & 5 deletions emain/emain-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function makeEditMenu(): Electron.MenuItemConstructorOptions[] {
];
}

function makeFileMenu(numWaveWindows: number, callbacks: AppMenuCallbacks): Electron.MenuItemConstructorOptions[] {
function makeFileMenu(numWaveWindows: number, callbacks: AppMenuCallbacks, fullConfig: FullConfigType): Electron.MenuItemConstructorOptions[] {
const fileMenu: Electron.MenuItemConstructorOptions[] = [
{
label: "New Window",
Expand All @@ -125,7 +125,8 @@ function makeFileMenu(numWaveWindows: number, callbacks: AppMenuCallbacks): Elec
},
},
];
if (isDev) {
const featureWaveAppBuilder = fullConfig?.settings?.["feature:waveappbuilder"];
if (isDev || featureWaveAppBuilder) {
fileMenu.splice(1, 0, {
label: "New WaveApp Builder Window",
accelerator: unamePlatform === "darwin" ? "Command+Shift+B" : "Alt+Shift+B",
Expand Down Expand Up @@ -310,18 +311,19 @@ function makeViewMenu(
async function makeFullAppMenu(callbacks: AppMenuCallbacks, workspaceOrBuilderId?: string): Promise<Electron.Menu> {
const numWaveWindows = getAllWaveWindows().length;
const webContents = workspaceOrBuilderId && getWebContentsByWorkspaceOrBuilderId(workspaceOrBuilderId);
const fileMenu = makeFileMenu(numWaveWindows, callbacks);
const appMenuItems = makeAppMenuItems(webContents);
const editMenu = makeEditMenu();

const isBuilderWindowFocused = focusedBuilderWindow != null;
let fullscreenOnLaunch = false;
let fullConfig: FullConfigType = null;
try {
const fullConfig = await RpcApi.GetFullConfigCommand(ElectronWshClient);
fullConfig = await RpcApi.GetFullConfigCommand(ElectronWshClient);
fullscreenOnLaunch = fullConfig?.settings["window:fullscreenonlaunch"];
} catch (e) {
console.error("Error fetching fullscreen launch config:", e);
console.error("Error fetching config:", e);
}
const fileMenu = makeFileMenu(numWaveWindows, callbacks, fullConfig);
const viewMenu = makeViewMenu(webContents, callbacks, isBuilderWindowFocused, fullscreenOnLaunch);
let workspaceMenu: Electron.MenuItemConstructorOptions[] = null;
try {
Expand Down
10 changes: 10 additions & 0 deletions emain/emain-platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,22 @@ function getWaveDataDir(): string {
}

function getElectronAppBasePath(): string {
// import.meta.dirname in dev points to waveterm/dist/main
return path.dirname(import.meta.dirname);
}

function getElectronAppUnpackedBasePath(): string {
return getElectronAppBasePath().replace("app.asar", "app.asar.unpacked");
}

function getElectronAppResourcesPath(): string {
if (isDev) {
// import.meta.dirname in dev points to waveterm/dist/main
return path.dirname(import.meta.dirname);
}
return process.resourcesPath;
}

const wavesrvBinName = `wavesrv.${unameArch}`;

function getWaveSrvPath(): string {
Expand Down Expand Up @@ -261,6 +270,7 @@ export {
callWithOriginalXdgCurrentDesktop,
callWithOriginalXdgCurrentDesktopAsync,
getElectronAppBasePath,
getElectronAppResourcesPath,
getElectronAppUnpackedBasePath,
getWaveConfigDir,
getWaveDataDir,
Expand Down
1 change: 1 addition & 0 deletions emain/emain-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as electron from "electron";
import { getWebServerEndpoint } from "../frontend/util/endpoints";

export const WaveAppPathVarName = "WAVETERM_APP_PATH";
export const WaveAppResourcesPathVarName = "WAVETERM_RESOURCES_PATH";
export const WaveAppElectronExecPath = "WAVETERM_ELECTRONEXECPATH";

export function getElectronExecPath(): string {
Expand Down
9 changes: 8 additions & 1 deletion emain/emain-wavesrv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { WebServerEndpointVarName, WSServerEndpointVarName } from "../frontend/u
import { AuthKey, WaveAuthKeyEnv } from "./authkey";
import { setForceQuit } from "./emain-activity";
import {
getElectronAppResourcesPath,
getElectronAppUnpackedBasePath,
getWaveConfigDir,
getWaveDataDir,
Expand All @@ -17,7 +18,12 @@ import {
WaveConfigHomeVarName,
WaveDataHomeVarName,
} from "./emain-platform";
import { getElectronExecPath, WaveAppElectronExecPath, WaveAppPathVarName } from "./emain-util";
import {
getElectronExecPath,
WaveAppElectronExecPath,
WaveAppPathVarName,
WaveAppResourcesPathVarName,
} from "./emain-util";
import { updater } from "./updater";

let isWaveSrvDead = false;
Expand Down Expand Up @@ -59,6 +65,7 @@ export function runWaveSrv(handleWSEvent: (evtMsg: WSEventType) => void): Promis
envCopy["XDG_CURRENT_DESKTOP"] = xdgCurrentDesktop;
}
envCopy[WaveAppPathVarName] = getElectronAppUnpackedBasePath();
envCopy[WaveAppResourcesPathVarName] = getElectronAppResourcesPath();
envCopy[WaveAppElectronExecPath] = getElectronExecPath();
envCopy[WaveAuthKeyEnv] = AuthKey;
envCopy[WaveDataHomeVarName] = getWaveDataDir();
Expand Down
10 changes: 2 additions & 8 deletions frontend/app/view/tsunami/tsunami.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,8 @@ class TsunamiViewModel extends WebViewModel {
oref: WOS.makeORef("block", blockId),
});
initialRTInfo.then((rtInfo) => {
if (rtInfo) {
const meta: AppMeta = {
title: rtInfo["tsunami:title"],
shortdesc: rtInfo["tsunami:shortdesc"],
icon: rtInfo["tsunami:icon"],
iconcolor: rtInfo["tsunami:iconcolor"],
};
globalStore.set(this.appMeta, meta);
if (rtInfo && rtInfo["tsunami:appmeta"]) {
globalStore.set(this.appMeta, rtInfo["tsunami:appmeta"]);
}
});
this.appMetaUnsubFn = waveEventSubscribe({
Expand Down
9 changes: 5 additions & 4 deletions frontend/app/workspace/widgets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ const Widgets = memo(() => {
magnified: true,
};
const showHelp = fullConfig?.settings?.["widget:showhelp"] ?? true;
const featureWaveAppBuilder = fullConfig?.settings?.["feature:waveappbuilder"] ?? false;
const widgetsMap = fullConfig?.widgets ?? {};
const filteredWidgets = hasCustomAIPresets
? widgetsMap
Expand Down Expand Up @@ -342,9 +343,9 @@ const Widgets = memo(() => {
))}
</div>
<div className="flex-grow" />
{isDev() || showHelp ? (
{isDev() || featureWaveAppBuilder || showHelp ? (
<div className="grid grid-cols-2 gap-0 w-full">
{isDev() ? (
{isDev() || featureWaveAppBuilder ? (
<div
ref={appsButtonRef}
className="flex flex-col justify-center items-center w-full py-1.5 pr-0.5 text-secondary text-sm overflow-hidden rounded-sm hover:bg-hoverbg hover:text-white cursor-pointer"
Expand Down Expand Up @@ -372,7 +373,7 @@ const Widgets = memo(() => {
<Widget key={`widget-${idx}`} widget={data} mode={mode} />
))}
<div className="flex-grow" />
{isDev() ? (
{isDev() || featureWaveAppBuilder ? (
<div
ref={appsButtonRef}
className="flex flex-col justify-center items-center w-full py-1.5 pr-0.5 text-secondary text-lg overflow-hidden rounded-sm hover:bg-hoverbg hover:text-white cursor-pointer"
Expand Down Expand Up @@ -407,7 +408,7 @@ const Widgets = memo(() => {
</div>
) : null}
</div>
{isDev() && appsButtonRef.current && (
{(isDev() || featureWaveAppBuilder) && appsButtonRef.current && (
<AppsFloatingWindow
isOpen={isAppsOpen}
onClose={() => setIsAppsOpen(false)}
Expand Down
6 changes: 2 additions & 4 deletions frontend/types/gotypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -914,10 +914,7 @@ declare global {

// waveobj.ObjRTInfo
type ObjRTInfo = {
"tsunami:title"?: string;
"tsunami:shortdesc"?: string;
"tsunami:icon"?: string;
"tsunami:iconcolor"?: string;
"tsunami:appmeta"?: AppMeta;
"tsunami:schemas"?: any;
"shell:hascurcwd"?: boolean;
"shell:state"?: string;
Expand Down Expand Up @@ -1030,6 +1027,7 @@ declare global {
"app:dismissarchitecturewarning"?: boolean;
"app:defaultnewblock"?: string;
"app:showoverlayblocknums"?: boolean;
"feature:waveappbuilder"?: boolean;
"ai:*"?: boolean;
"ai:preset"?: string;
"ai:apitype"?: string;
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 21 additions & 8 deletions pkg/aiusechat/tools_tsunami.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,23 @@ import (

"github.com/wavetermdev/waveterm/pkg/aiusechat/uctypes"
"github.com/wavetermdev/waveterm/pkg/blockcontroller"
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
"github.com/wavetermdev/waveterm/pkg/waveobj"
"github.com/wavetermdev/waveterm/pkg/wshrpc"
"github.com/wavetermdev/waveterm/pkg/wstore"
)

func getTsunamiShortDesc(rtInfo *waveobj.ObjRTInfo) string {
if rtInfo == nil || rtInfo.TsunamiAppMeta == nil {
return ""
}
var appMeta wshrpc.AppMeta
if err := utilfn.ReUnmarshal(&appMeta, rtInfo.TsunamiAppMeta); err == nil && appMeta.ShortDesc != "" {
return appMeta.ShortDesc
}
return ""
}

func handleTsunamiBlockDesc(block *waveobj.Block) string {
status := blockcontroller.GetBlockControllerRuntimeStatus(block.OID)
if status == nil || status.ShellProcStatus != blockcontroller.Status_Running {
Expand All @@ -25,8 +38,8 @@ func handleTsunamiBlockDesc(block *waveobj.Block) string {

blockORef := waveobj.MakeORef(waveobj.OType_Block, block.OID)
rtInfo := wstore.GetRTInfo(blockORef)
if rtInfo != nil && rtInfo.TsunamiShortDesc != "" {
return fmt.Sprintf("tsunami widget - %s", rtInfo.TsunamiShortDesc)
if shortDesc := getTsunamiShortDesc(rtInfo); shortDesc != "" {
return fmt.Sprintf("tsunami widget - %s", shortDesc)
}
return "tsunami widget - unknown description"
}
Expand Down Expand Up @@ -111,8 +124,8 @@ func GetTsunamiGetDataToolDefinition(block *waveobj.Block, rtInfo *waveobj.ObjRT
toolName := fmt.Sprintf("tsunami_getdata_%s", blockIdPrefix)

desc := "tsunami widget"
if rtInfo != nil && rtInfo.TsunamiShortDesc != "" {
desc = rtInfo.TsunamiShortDesc
if shortDesc := getTsunamiShortDesc(rtInfo); shortDesc != "" {
desc = shortDesc
}

return &uctypes.ToolDefinition{
Expand All @@ -136,8 +149,8 @@ func GetTsunamiGetConfigToolDefinition(block *waveobj.Block, rtInfo *waveobj.Obj
toolName := fmt.Sprintf("tsunami_getconfig_%s", blockIdPrefix)

desc := "tsunami widget"
if rtInfo != nil && rtInfo.TsunamiShortDesc != "" {
desc = rtInfo.TsunamiShortDesc
if shortDesc := getTsunamiShortDesc(rtInfo); shortDesc != "" {
desc = shortDesc
}

return &uctypes.ToolDefinition{
Expand Down Expand Up @@ -174,8 +187,8 @@ func GetTsunamiSetConfigToolDefinition(block *waveobj.Block, rtInfo *waveobj.Obj
}

desc := "tsunami widget"
if rtInfo != nil && rtInfo.TsunamiShortDesc != "" {
desc = rtInfo.TsunamiShortDesc
if shortDesc := getTsunamiShortDesc(rtInfo); shortDesc != "" {
desc = shortDesc
}

return &uctypes.ToolDefinition{
Expand Down
Loading
Loading