diff --git a/docs/docs/releasenotes.mdx b/docs/docs/releasenotes.mdx index 430a0394a3..f8ea51829e 100644 --- a/docs/docs/releasenotes.mdx +++ b/docs/docs/releasenotes.mdx @@ -6,6 +6,26 @@ sidebar_position: 200 # Release Notes +### v0.12.2 — Nov 4, 2025 + +Wave v0.12.2 adds file editing ability to Wave AI. Before approving a file edit you can easily see a diff (rendered in the Monaco Editor diff viewer), and after approving an edit you can easily roll back the change using a "Revert File" button. + +**Wave AI Updates:** +- **File Write Tool** - Wave AI can now create and modify files with your approval +- **Visual Diff Preview** - See exactly what will change before approving edits, rendered in Monaco Editor +- **Easy Rollback** - Revert file changes with a simple "Revert File" button +- **Drag & Drop Files** - Drag files from the preview viewer directly to Wave AI +- **Directory Listings** - `wsh ai` can now attach directory listings to chats +- **Adjustable Settings** - Control thinking level and max output tokens per chat + +**Bug Fixes & Improvements:** +- Fixed a significant memory leak in the RPC system +- Schema validation working again for config files +- Improved tool descriptions and input validations (run before tool approvals) +- Fixed issue with premature tool timeouts +- Fixed regression with PowerShell 5.x +- Fixed prompt caching issue when attaching files + ### v0.12.1 — Oct 20, 2025 Patch release focused on shell integration improvements and Wave AI enhancements. This release fixes syntax highlighting in the code editor and adds significant shell context tracking capabilities. diff --git a/docs/docs/telemetry.mdx b/docs/docs/telemetry.mdx index 9689f2791e..958e6e3538 100644 --- a/docs/docs/telemetry.mdx +++ b/docs/docs/telemetry.mdx @@ -76,6 +76,7 @@ Below is a list of the event types collected in the new telemetry system. More e | `debug:panic` | Logged when a backend (Go) panic happens. Contains a debugging string that can be used to find which panic was hit in our source code. No data is sent | | `conn:connect` | Logged each time a backend ssh/wsl connection connects (logs the conneciton type, no hostname or IP is sent) | | `conn:connecterror` | Logged when you try to connect but it fails (logs the connection type, no hostname or IP is set, and no detailed error information is sent) | +| `waveai:post` | Logged after AI request completion with usage metrics (tokens, request counts, latency, etc. - no prompts or responses) | ## Event Properties @@ -115,6 +116,24 @@ Each event may contain the following properties that are relevant to the particu | `count:sshconn` | Total number of SSH connections | | `count:wslconn` | Total number of WSL connections | | `count:views` | Counts of the types of blocks (views) | +| `waveai:apitype` | AI API provider (OpenAI, Anthropic, etc.) | +| `waveai:model` | AI model name | +| `waveai:inputtokens` | Number of input tokens used | +| `waveai:outputtokens` | Number of output tokens generated | +| `waveai:requestcount` | Number of requests in conversation | +| `waveai:toolusecount` | Number of tool uses | +| `waveai:tooluseerrorcount` | Number of tool use errors | +| `waveai:tooldetail` | Map of tool names to usage counts | +| `waveai:premiumreq` | Number of premium API requests | +| `waveai:proxyreq` | Number of proxy requests | +| `waveai:haderror` | True/False if request had errors | +| `waveai:imagecount` | Number of images in context | +| `waveai:pdfcount` | Number of PDFs in context | +| `waveai:textdoccount` | Number of text documents in context | +| `waveai:textlen` | Total text length in context | +| `waveai:firstbytems` | Latency to first byte in milliseconds | +| `waveai:requestdurms` | Total request duration in milliseconds | +| `waveai:widgetaccess` | True/False if accessed via widget | --- diff --git a/docs/docs/waveai.mdx b/docs/docs/waveai.mdx index 65ffade29f..e352865ef9 100644 --- a/docs/docs/waveai.mdx +++ b/docs/docs/waveai.mdx @@ -42,6 +42,18 @@ Drag files onto the AI panel to attach: | PDFs | `.pdf` | 5 MB | Text extraction for analysis | | Text/Code | `.js`, `.ts`, `.py`, `.go`, `.md`, `.json`, `.yaml`, etc. | 200 KB | All common languages and configs | +## CLI Integration + +Use `wsh ai` to send files and prompts from the command line: + +```bash +git diff | wsh ai - # Pipe to AI +wsh ai main.go -m "find bugs" # Attach files with message +wsh ai $(tail -n 500 my.log) -m "review" -s # Auto-submit with output +``` + +Supports text files, images, PDFs, and directories. Use `-n` for new chat, `-s` to auto-submit. + ## AI Tools (Widget Context Enabled) ### Terminal @@ -50,6 +62,7 @@ Drag files onto the AI panel to attach: ### File System - **Read Files**: Reads text files with line range support (requires approval) - **List Directories**: Returns file info, sizes, permissions, timestamps (requires approval) +- **Write Text Files**: Create or modify files with diff preview and approval (requires approval) ### Web - **Navigate Web**: Changes URLs in web browser widgets @@ -72,10 +85,8 @@ File system operations require explicit approval. You control all file access. Wave AI is in active beta with included AI credits while we refine the experience. BYOK will be available once we've stabilized core features and gathered feedback on what works best. Share feedback in our [Discord](https://discord.gg/XfvZ334gwU). **Coming Soon:** -- **CLI Integration**: Send files and chat prompts directly from the command line - **Remote File Access**: Read files on SSH-connected systems - **Command Execution**: Run terminal commands with approval -- **File Editing**: Modify files with approval or open in editor widgets - **Web Content**: Extract text from web pages (currently screenshots only) ::: diff --git a/frontend/app/onboarding/onboarding-common.tsx b/frontend/app/onboarding/onboarding-common.tsx index 80cec552c2..d0c71a1836 100644 --- a/frontend/app/onboarding/onboarding-common.tsx +++ b/frontend/app/onboarding/onboarding-common.tsx @@ -1,4 +1,4 @@ // Copyright 2025, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -export const CurrentOnboardingVersion = "v0.12.1"; +export const CurrentOnboardingVersion = "v0.12.2"; diff --git a/frontend/app/onboarding/onboarding-features.tsx b/frontend/app/onboarding/onboarding-features.tsx index b5f1706c4c..69d34a9514 100644 --- a/frontend/app/onboarding/onboarding-features.tsx +++ b/frontend/app/onboarding/onboarding-features.tsx @@ -12,8 +12,8 @@ import { TabRpcClient } from "@/app/store/wshrpcutil"; import { isMacOS } from "@/util/platformutil"; import { useEffect, useState } from "react"; import { FakeChat } from "./fakechat"; -import { CurrentOnboardingVersion } from "./onboarding-common"; import { EditBashrcCommand, ViewLogoCommand, ViewShortcutsCommand } from "./onboarding-command"; +import { CurrentOnboardingVersion } from "./onboarding-common"; import { FakeLayout } from "./onboarding-layout"; type FeaturePageName = "waveai" | "magnify" | "files"; @@ -100,7 +100,7 @@ const WaveAIPage = ({ onNext, onSkip }: { onNext: () => void; onSkip: () => void

Wave AI is your terminal assistant with context. I can read your terminal output, - analyze widgets, access files, and help you solve problems faster. + analyze widgets, read/write files, and help you solve problems faster.

diff --git a/frontend/app/onboarding/onboarding-upgrade-patch.tsx b/frontend/app/onboarding/onboarding-upgrade-patch.tsx new file mode 100644 index 0000000000..8bfd0e0fc1 --- /dev/null +++ b/frontend/app/onboarding/onboarding-upgrade-patch.tsx @@ -0,0 +1,165 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +import Logo from "@/app/asset/logo.svg"; +import { Button } from "@/app/element/button"; +import { FlexiModal } from "@/app/modals/modal"; +import { CurrentOnboardingVersion } from "@/app/onboarding/onboarding-common"; +import { atoms, globalStore } from "@/app/store/global"; +import { disableGlobalKeybindings, enableGlobalKeybindings, globalRefocus } from "@/app/store/keymodel"; +import { modalsModel } from "@/app/store/modalmodel"; +import * as WOS from "@/app/store/wos"; +import { RpcApi } from "@/app/store/wshclientapi"; +import { TabRpcClient } from "@/app/store/wshrpcutil"; +import { OverlayScrollbarsComponent } from "overlayscrollbars-react"; +import { useEffect, useRef, useState } from "react"; +import { debounce } from "throttle-debounce"; +import { UpgradeOnboardingModal_v0_12_1_Content } from "./onboarding-upgrade-v0121"; +import { UpgradeOnboardingModal_v0_12_2_Content } from "./onboarding-upgrade-v0122"; + +interface VersionConfig { + version: string; + content: () => React.ReactNode; + prevText?: string; + nextText?: string; +} + +const versions: VersionConfig[] = [ + { + version: "v0.12.1", + content: () => , + nextText: "Next (v0.12.2)", + }, + { + version: "v0.12.2", + content: () => , + prevText: "Prev (v0.12.1)", + }, +]; + +const UpgradeOnboardingPatch = () => { + const modalRef = useRef(null); + const [isCompact, setIsCompact] = useState(window.innerHeight < 800); + const [currentIndex, setCurrentIndex] = useState(versions.length - 1); + + const currentVersion = versions[currentIndex]; + const hasPrev = currentIndex > 0; + const hasNext = currentIndex < versions.length - 1; + + const updateModalHeight = () => { + const windowHeight = window.innerHeight; + setIsCompact(windowHeight < 800); + if (modalRef.current) { + const modalHeight = modalRef.current.offsetHeight; + const maxHeight = windowHeight * 0.9; + if (maxHeight < modalHeight) { + modalRef.current.style.height = `${maxHeight}px`; + } else { + modalRef.current.style.height = "auto"; + } + } + }; + + useEffect(() => { + updateModalHeight(); + const debouncedUpdateModalHeight = debounce(150, updateModalHeight); + window.addEventListener("resize", debouncedUpdateModalHeight); + return () => { + window.removeEventListener("resize", debouncedUpdateModalHeight); + }; + }, []); + + useEffect(() => { + disableGlobalKeybindings(); + return () => { + enableGlobalKeybindings(); + }; + }, []); + + const handleClose = () => { + const clientId = globalStore.get(atoms.clientId); + RpcApi.SetMetaCommand(TabRpcClient, { + oref: WOS.makeORef("client", clientId), + meta: { "onboarding:lastversion": CurrentOnboardingVersion }, + }); + globalStore.set(modalsModel.upgradeOnboardingOpen, false); + setTimeout(() => { + globalRefocus(); + }, 10); + }; + + const paddingClass = isCompact ? "!py-3 !px-[30px]" : "!p-[30px]"; + + const handlePrev = () => { + if (hasPrev) { + setCurrentIndex(currentIndex - 1); + } + }; + + const handleNext = () => { + if (hasNext) { + setCurrentIndex(currentIndex + 1); + } + }; + + return ( + +
+
+
+
+
+ +
+
+ Wave {currentVersion.version} Update +
+
+ + {currentVersion.content()} + +
+
+
+ {hasPrev && ( +
+ +
+ )} +
+
+ +
+
+ {hasNext && ( +
+ +
+ )} +
+
+
+
+
+ + ); +}; + +UpgradeOnboardingPatch.displayName = "UpgradeOnboardingPatch"; + +export { UpgradeOnboardingPatch }; diff --git a/frontend/app/onboarding/onboarding-upgrade-v0121.tsx b/frontend/app/onboarding/onboarding-upgrade-v0121.tsx index 051b623cb7..53649c31da 100644 --- a/frontend/app/onboarding/onboarding-upgrade-v0121.tsx +++ b/frontend/app/onboarding/onboarding-upgrade-v0121.tsx @@ -1,170 +1,80 @@ // Copyright 2025, Command Line Inc. // SPDX-License-Identifier: Apache-2.0 -import Logo from "@/app/asset/logo.svg"; -import { Button } from "@/app/element/button"; -import { FlexiModal } from "@/app/modals/modal"; -import { CurrentOnboardingVersion } from "@/app/onboarding/onboarding-common"; -import { atoms, globalStore } from "@/app/store/global"; -import { disableGlobalKeybindings, enableGlobalKeybindings, globalRefocus } from "@/app/store/keymodel"; -import { modalsModel } from "@/app/store/modalmodel"; -import * as WOS from "@/app/store/wos"; -import { RpcApi } from "@/app/store/wshclientapi"; -import { TabRpcClient } from "@/app/store/wshrpcutil"; -import { OverlayScrollbarsComponent } from "overlayscrollbars-react"; -import { useEffect, useRef, useState } from "react"; -import { debounce } from "throttle-debounce"; - -const UpgradeOnboardingModal_v0_12_1 = () => { - const modalRef = useRef(null); - const [isCompact, setIsCompact] = useState(window.innerHeight < 800); - - const updateModalHeight = () => { - const windowHeight = window.innerHeight; - setIsCompact(windowHeight < 800); - if (modalRef.current) { - const modalHeight = modalRef.current.offsetHeight; - const maxHeight = windowHeight * 0.9; - if (maxHeight < modalHeight) { - modalRef.current.style.height = `${maxHeight}px`; - } else { - modalRef.current.style.height = "auto"; - } - } - }; - - useEffect(() => { - updateModalHeight(); - const debouncedUpdateModalHeight = debounce(150, updateModalHeight); - window.addEventListener("resize", debouncedUpdateModalHeight); - return () => { - window.removeEventListener("resize", debouncedUpdateModalHeight); - }; - }, []); - - useEffect(() => { - disableGlobalKeybindings(); - return () => { - enableGlobalKeybindings(); - }; - }, []); - - const handleClose = () => { - const clientId = globalStore.get(atoms.clientId); - RpcApi.SetMetaCommand(TabRpcClient, { - oref: WOS.makeORef("client", clientId), - meta: { "onboarding:lastversion": CurrentOnboardingVersion }, - }); - globalStore.set(modalsModel.upgradeOnboardingOpen, false); - setTimeout(() => { - globalRefocus(); - }, 10); - }; - - const paddingClass = isCompact ? "!py-3 !px-[30px]" : "!p-[30px]"; - +const UpgradeOnboardingModal_v0_12_1_Content = () => { return ( - -
-
-
-
-
- -
-
Wave v0.12.1 Update
-
- -
-
-

- Patch release focused on shell integration improvements, Wave AI enhancements, and - restoring syntax highlighting in code editor blocks. -

-
+
+
+

+ Patch release focused on shell integration improvements, Wave AI enhancements, and restoring syntax + highlighting in code editor blocks. +

+
-
-
- -
-
-
- Shell Integration & Context -
-
-
    -
  • - OSC 7 Support - Wave now automatically tracks and - restores your current directory across restarts for bash, zsh, fish, and - pwsh shells -
  • -
  • - Shell Context Tracking - Tracks when your shell is - ready, last command executed, and exit codes for better terminal - management -
  • -
-
-
-
+
+
+ +
+
+
+ Shell Integration & Context +
+
+
    +
  • + OSC 7 Support - Wave now automatically tracks and restores your current + directory across restarts for bash, zsh, fish, and pwsh shells +
  • +
  • + Shell Context Tracking - Tracks when your shell is ready, last command + executed, and exit codes for better terminal management +
  • +
+
+
+
-
-
- -
-
-
- Wave AI Improvements -
-
-
    -
  • Display reasoning summaries while waiting for AI responses
  • -
  • - Enhanced terminal context - AI now has access to shell state, current - directory, command history, and exit codes -
  • -
  • Added feedback buttons (thumbs up/down) for AI responses
  • -
  • Added copy button to easily copy AI responses to clipboard
  • -
-
-
-
+
+
+ +
+
+
+ Wave AI Improvements +
+
+
    +
  • Display reasoning summaries while waiting for AI responses
  • +
  • + Enhanced terminal context - AI now has access to shell state, current directory, command + history, and exit codes +
  • +
  • Added feedback buttons (thumbs up/down) for AI responses
  • +
  • Added copy button to easily copy AI responses to clipboard
  • +
+
+
+
-
-
- -
-
-
- Other Changes -
-
-
    -
  • Mobile user agent emulation support for web widgets
  • -
  • Fixed padding for header buttons in code editor
  • -
  • Restored syntax highlighting in code editor preview blocks
  • -
-
-
-
-
- -
-
- -
-
+
+
+ +
+
+
Other Changes
+
+
    +
  • Mobile user agent emulation support for web widgets
  • +
  • Fixed padding for header buttons in code editor
  • +
  • Restored syntax highlighting in code editor preview blocks
  • +
+
- +
); }; -UpgradeOnboardingModal_v0_12_1.displayName = "UpgradeOnboardingModal_v0_12_1"; +UpgradeOnboardingModal_v0_12_1_Content.displayName = "UpgradeOnboardingModal_v0_12_1_Content"; -export { UpgradeOnboardingModal_v0_12_1 }; +export { UpgradeOnboardingModal_v0_12_1_Content }; diff --git a/frontend/app/onboarding/onboarding-upgrade-v0122.tsx b/frontend/app/onboarding/onboarding-upgrade-v0122.tsx new file mode 100644 index 0000000000..723672a357 --- /dev/null +++ b/frontend/app/onboarding/onboarding-upgrade-v0122.tsx @@ -0,0 +1,82 @@ +// Copyright 2025, Command Line Inc. +// SPDX-License-Identifier: Apache-2.0 + +const UpgradeOnboardingModal_v0_12_2_Content = () => { + return ( +
+
+

+ Wave AI can now create and modify files with visual diff previews and easy rollback capabilities. + Plus performance improvements and bug fixes. +

+
+ +
+
+ +
+
+
Wave AI File Editing
+
+
    +
  • + File Write Tool - Wave AI can now create and modify files with your + approval +
  • +
  • + Visual Diff Preview - See exactly what will change before approving + edits +
  • +
  • + Easy Rollback - Revert file changes with a simple "Revert File" button +
  • +
+
+
+
+ +
+
+ +
+
+
+ Additional AI Improvements +
+
+
    +
  • Drag & drop files from preview viewer directly to Wave AI
  • +
  • + Directory listings support in `wsh ai` commands +
  • +
  • Adjustable thinking level and max output tokens per chat
  • +
  • Improved tool descriptions and input validations
  • +
+
+
+
+ +
+
+ +
+
+
+ Bug Fixes & Improvements +
+
+
    +
  • Fixed significant memory leak in the RPC system
  • +
  • Config file schema validation restored
  • +
  • Fixed PowerShell 5.x regression
  • +
+
+
+
+
+ ); +}; + +UpgradeOnboardingModal_v0_12_2_Content.displayName = "UpgradeOnboardingModal_v0_12_2_Content"; + +export { UpgradeOnboardingModal_v0_12_2_Content }; diff --git a/frontend/app/onboarding/onboarding-upgrade.tsx b/frontend/app/onboarding/onboarding-upgrade.tsx index c2c7a98537..e8b45ecd3b 100644 --- a/frontend/app/onboarding/onboarding-upgrade.tsx +++ b/frontend/app/onboarding/onboarding-upgrade.tsx @@ -7,7 +7,7 @@ import { useAtomValue } from "jotai"; import { useEffect, useRef } from "react"; import * as semver from "semver"; import { UpgradeOnboardingModal_v0_12_0 } from "./onboarding-upgrade-v0120"; -import { UpgradeOnboardingModal_v0_12_1 } from "./onboarding-upgrade-v0121"; +import { UpgradeOnboardingPatch } from "./onboarding-upgrade-patch"; const UpgradeOnboardingModal = () => { const clientData = useAtomValue(atoms.client); @@ -20,17 +20,17 @@ const UpgradeOnboardingModal = () => { const lastVersion = initialVersionRef.current; useEffect(() => { - if (semver.gte(lastVersion, "v0.12.1")) { + if (semver.gte(lastVersion, "v0.12.2")) { globalStore.set(modalsModel.upgradeOnboardingOpen, false); } }, [lastVersion]); - if (semver.gte(lastVersion, "v0.12.1")) { + if (semver.gte(lastVersion, "v0.12.2")) { return null; } if (semver.gte(lastVersion, "v0.12.0")) { - return ; + return ; } return ;