This adds an RPC command for updating wsh on a remote machine without
starting a new session. It is not being used yet, but will be used for
connections using a single server in the future.
lots of misc connection refactoring / fixes:
* adds blocklogger as a way to writing logging information from the backend directly to the a terminal block
* use blocklogger in conncontroller
* use blocklogger in sshclient
* fix remote name in password prompt
* use sh -c to get around shell weirdness
* remove cmd.exe special cases
* use GetWatcher().GetFullConfig() rather than re-reading the config file
* change order of things we do when establishing a connection. ask for wsh up front. then do domain socket, then connserver
* reduce number of sessions required in the common case when wsh is already installed. running the connserver is now a "multi-command" which checks if it is installed, then asks for the version
* send jwt token over stdin instead of in initial command string
* fix focus bug for frontend conn modal
* track more information in connstatus
* simplify wshinstall function
* add nowshreason
* other misc cleanup
* use pwsh over powershell if installed (on windows) for default shell
* refactor blockcontroller.DoRunShellCommand into a "setup" and "manage" phase
* fix wshcmd-conn to also disconnect wsl connections
* new genconn interfaces to make a standardized environment to run SSH/WSL commands via `sh -c`. also create better quoting functions that are composable
* replace html/template with text/template for shell command templating (avoids special chars getting turned into HTML entities, breaking the commands)
* do not reinstall wsh if the installed version has a higher version (prevents flip-flopping on shared systems)
* simplify clientOs/clientArch detection. use `uname -sm`. also validate the os/arch combo as compatible with our builds.
* replace CpHostToRemote with CpWshToRemote. hard codes wsh paths inside of the function instead of having them passed in (quoting restrictions)
* new SyncBuffer class to use with commands that properly synchronizes Writes/String output
* fix setTermSize to actually update DB with terminal size
The terminal keydown handler was set to filter out all key bindings that
have a registered global handler, regardless of whether they actually
propagated or not. This allowed the global handlers to still work
despite the terminal input having precedence, but it also meant that
global key bindings that were invalid for the current context would
still get eaten and not sent to stdin.
Now, the terminal keydown handler will directly call the global handlers
so we can actually see whether or not the global key binding is valid.
If the global handler is valid, it'll be processed immediately and stdin
won't receive the input. If it's not handled, we'll let xterm pass it to
stdin. Because anything xterm doesn't handle gets sent to the
globally-registered version of the handler, we need to make sure we
don't do extra work to process an input we've already checked. We'll
store the last-handled keydown event as a static variable so we can
dedupe later calls for the same event to prevent doing double work.
This adds support for searching the terminal buffer using the
`@xterm/addon-search` library. It also adds three options for searching:
regex, case-sensitive, and whole-word. These can be included or excluded
from the search options for `useSearch` depending on whether the search
backend supports it.

I didn't like any of the Font Awesome icons for these toggles so until
we have time to make some of our own icons that better match the Font
Awesome style, I've appropriated VSCode's icons from their [codicons
font](https://github.com/microsoft/vscode-codicons).
To implement the toggle-able buttons for these options, I've introduced
a new HeaderElem component, `ToggleIconButton`. This is styled similarly
to `IconButton`, but when you hover over it, it also shows a highlighted
background and when active, it shows as fully-opaque and with an
accented border.
Also removes the `useDismiss` behavior for the search box to better
match behavior in other apps.
Also fixes the scrollbar observer from my previous PR so it's wider.
I did not mean to close the previous pr, anyway i tried to implement
what you suggested, the backend now does most of it
and DeleteWorkspace will return an unclaimed id and avoid closing the
window.
```go
const moveToNewWorkspace = await WorkspaceService.DeleteWorkspace(workspaceId)
console.log("delete-workspace done", workspaceId, ww?.waveWindowId);
if (ww?.workspaceId == workspaceId){
if ( workspaceList?.length > 1 ) {
await ww.switchWorkspace(moveToNewWorkspace)
} else {
console.log("delete-workspace closing window", workspaceId, ww?.waveWindowId);
ww.destroy();
}
}
});
```


---------
Co-authored-by: Evan Simkowitz <esimkowitz@users.noreply.github.com>
A bunch of the Wave AI types still mentioned OpenAI. Now that most of
them are being used for multiple AI backends, we need to update the
names to be more generic.
Also moves icon and color definitions to the backend and makes it so the
new workspaces get created with a different icon color for each index.
If an ephemeral window has more than one tab, always create a new window
when switching workspaces
Also fixes workspace accelerators on macOS
Sometimes, the context menu click handlers don't seem to get passed any
window object. Here, I'm sending over the workspace id with the
`contextmenu-show` event so that we can resolve our cached copy of the
object in case the value from the click handler is empty.
Adds a new app menu for creating a new workspace or switching to an
existing one. This required adding a new WPS event any time a workspace
gets updated, since the Electron app menus are static.
This also fixes a bug where closing a workspace could delete it if it
didn't have both a pinned and an unpinned tab.
fixes bug with closeTab when the tab didn't exist in the waveWindow cache. also adds Cmd-Shift-W to close a tab (doesn't work for pinned tabs). and restores Cmd-W for killing blocks on pinned tabs
This adds the following connections changes:
- connections can be hidden from the dropdown in our internal
connections.json config
- `wsh ssh` -i will write identity files to the internal
connections.json config for that connection
- the internal connections.json config will also be used to get identity
files when connecting
- the internal connections.json config allows setting theme, fontsize,
and font for specific connections
- successful connections (including those using wsh ssh) are saved to
the internal connections.json config
- the connections.json config will be used to help pre-populate the
dropdown list
- adds an item to the dropdown to edit the connections config in an
ephemeral block
---------
Co-authored-by: Evan Simkowitz <esimkowitz@users.noreply.github.com>
There was still some flicker when nohover took effect before the tab
view actually switched. Now, we override the active tab in the tabbar
when the app is switching tabs. We also override active tab behavior so
that the close button is always visible while nohover is in effect. This
effectively removes the flickering

This functions very similarly to VSCode's pinned tab feature. To pin a
tab, you can right-click on it and select "Pin tab" from the context
menu. Once pinned, a tab will be fixed to the left-most edge of the tab
bar, in order of pinning. Pinned tabs can be dragged around like any
others. If you drag an unpinned tab into the pinned tabs section (any
index less than the highest-index pinned tab), it will be pinned. If you
drag a pinned tab out of the pinned tab section, it will be unpinned.
Pinned tabs' close button is replaced with a persistent pin button,
which can be clicked to unpin them. This adds an extra barrier to
accidentally closing a pinned tab. They can still be closed from the
context menu.
New context menu options are available in the directory preview to
create and rename files and directories
It's missing three pieces of functionality, none of which are a
regression:
- Editing or creating an entry does not update the focused index. Focus
index right now is pretty dumb, it doesn't factor in the column sorting
so if you change that, the selected item will change to whatever is now
at that index. We should update this so we use the actual file name to
determine which element to focus and let the table determine which index
to then highlight given the current sorting algo
- Open in native preview should not be an option on remote connections
with the exception of WSL, where it should resolve the file in the
Windows filesystem, rather than the WSL one
- We should catch CRUD errors in the dir preview and display a popup
Ephemeral blocks can now be added to the LayoutModel for a tab. Only one
ephemeral block can exist at a time. It is placed above all other
blocks, including the magnified blocks.
Updates how magnified and ephemeral blocks overlay the other blocks.
Now, there's a blurred backdrop behind them that will obscure the other
blocks. As a result of this, the overlayed blocks are now translucent.
Lots of quality of life improvements (and bug fixes):
* Class(), ClassIf(), ClassIfElse() methods
* <wave:style> that can use a file vdom:/// url
* UseStateWithFn() to allow for functional setters
* If, IfElse, and ForEach for vdom construction
* batched updates for large updates -- streaming -- to get around packet size issues
* more flexible file sending code, for []byte, io.Reader, fs.File, and a fileName (with optional MimeType)
* fix the vdom:// protocol handler to work with fetch
* updated wshcmd-html for new best practices