Don't allow tabs with active Wave AI sessions to get closed when we
close the last block. Have Cmd-W close Wave AI if it is focused (rather
than a random node). Also fixes some lurking bugs with the pinned tab
functionality (and adds some nice visual feedback when we try to close a
pinned tab).
- [x] Explore repository structure and understand existing tools pattern
- [x] Create tools_readdir.go file with read_dir tool implementation
- [x] Add GetReadDirToolDefinition() function following the pattern of
read_text_file
- [x] Register the new tool in tools.go GenerateTabStateAndTools
function
- [x] Create comprehensive tests in tools_readdir_test.go
- [x] Test the implementation manually with various scenarios
- [x] Run Go tests to ensure no regressions
- [x] Run security check with CodeQL - No vulnerabilities found
- [x] Revert unintended changes to tsunami demo go.mod and go.sum files
- [x] Fix sorting to happen before truncation and preserve real total
count
## Summary
Successfully implemented a new `read_dir` AI tool that reads and lists
directory contents, following the same pattern as the existing
`read_text_file` tool.
**Key Features:**
- Supports path expansion (including ~)
- Sorts directories first, then files (sorting happens BEFORE
truncation)
- Truncates output to prevent overwhelming responses (default 1000
entries)
- Preserves the real total count even when truncated
- Requires user approval for security
- Provides detailed file/directory information (name, type, size,
permissions, modification time)
- Returns both structured data and formatted listing
**Files Changed:**
- `pkg/aiusechat/tools_readdir.go` - Main implementation (189 lines)
- `pkg/aiusechat/tools_readdir_test.go` - Comprehensive tests (211
lines)
- `pkg/aiusechat/tools.go` - Tool registration (1 line)
**Testing:**
- ✅ All 6 unit tests passing (including new test for
sort-before-truncate)
- ✅ Manual testing with real directories successful
- ✅ CodeQL security scan passed with no vulnerabilities
- ✅ Go build and vet successful
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
> Right now we have AI tools in go at pkg/aichat ... see tools.go,
tools_readfile.go. i'd like to add a new tool to read directories in the
style of readfile.
</details>
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
Co-authored-by: sawka <mike@commandline.dev>
### What This Does
Adds a new `wsh blocks list` subcommand that lists all blocks in all or
specified workspace, window, or tab. Includes filtering options and JSON
output for automation.
### Motivation
Wave users had no simple way to programmatically discover block IDs for
scripting and automation. This feature:
- Enables workflows like syncing Preview widgets with `cd` changes.
- Simplifies debugging and introspection.
- Provides a foundation for future CLI enhancements (focus/close
blocks).
### Usage
```wsh blocks [list|ls|get] [--workspace=<workspace-id>] [--window=<window-id>] [--tab=<tab-id>] [--view=<view-type>] [--json]```
Where `<view-type>` can be one of: term, terminal, shell, console, web, browser, url, preview, edit, sysinfo, sys, system, waveai, ai, or assistant.
### Notes
- Fully backward compatible.
- Code follows existing CLI patterns.
Massive PR, over 13k LOC updated, 128 commits to implement the first pass at the new Wave AI panel. Two backend adapters (OpenAI and Anthropic), layout changes to support the panel, keyboard shortcuts, and a huge focus/layout change to integrate the panel seamlessly into the UI.
Also fixes some small issues found during the Wave AI journey (zoom fixes, documentation, more scss removal, circular dependency issues, settings, etc)
The current layout system uses a complex bidirectional atom architecture
that forces every layout change to round-trip through the backend
WaveObject, even though **the backend never reads this data** - it only
queues actions via `PendingBackendActions`. By switching to a "write
cache" pattern where local atoms are the source of truth and backend
writes are fire-and-forget, we can eliminate ~70% of the complexity
while maintaining full persistence.
----
Every layout change (split, close, focus, magnify) currently follows
this flow:
```
User action
↓
treeReducer() mutates layoutState
↓
layoutState.generation++ ← Only purpose: trigger the write
↓
Bidirectional atom setter (checks generation)
↓
Write to WaveObject {rootnode, focusednodeid, magnifiednodeid}
↓
WaveObject update notification
↓
Bidirectional atom getter runs
↓
ALL dependent atoms recalculate (every isFocused, etc.)
↓
React re-renders with updated state
```
---
## Proposed "Write Cache" Architecture
### Core Concept
```
User action
↓
Update LOCAL atom (immediate, synchronous)
↓
React re-renders (single tick, all atoms see new state)
↓
[async, fire-and-forget] Persist to WaveObject
```
### Key Principles
1. **Local atoms are source of truth** during runtime
2. **WaveObject is persistence layer** only (read on init, write async)
3. **Backend actions still work** via `PendingBackendActions`
4. **No generation tracking needed** (no need to trigger writes)
checkpoint. good to merge. we have a working tsunami view inside of wave (with lots of caveats). but enough for some dev testing. merge so we dont drift too far from main and while we're at a stable point.
Working on AI SDK compatible backends for OpenAI and Anthropic. Thinking + ToolUse etc. For use with AI SDK useChat on frontend. Still needs more testing, WIP, but this is a good start. Want to get this committed to so I can work on more integrations.
Because I am on an internal network, I need to use a proxy server to
access Claude's services. However, Wave currently does not provide the
ability to configure the base URL, so I have added this feature in hopes
of being able to use it.
---------
Co-authored-by: sawka <mike@commandline.dev>
Gracefully handle prefix paths that don't exist, representing them as
directories so they can be escaped from.
Also removes the ".." file info from the backend, instead only creating
it on the frontend
Adds the S3 `fileshare` implementation
This also updates `wsh file cp` so it behaves more like `cp` for things
like copying directories and directory entries. It's not meant to align
with `cp` on everything, though. Our `wsh cp` will be recursive and will
create intermediate directories by default.
This also adds new aliases for `wsh view`: `wsh preview` and `wsh open`
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: sawka <mike@commandline.dev>
Co-authored-by: Sylvia Crowe <software@oneirocosm.com>
While there is significant overlap between SettingsType and
AiSettingsType, they are distinct entities and should be treated as such
until more changes have been made.
This allows code generation to properly embed structs when embedded in
the original types. It affects the generation of `gotypes.d.ts` and
`metaconsts.go`.
Additionally, the `AiSettingsType` has been split off and embedded into
the original `SettingsType` to make schema generation easier.
Let's you drag and drop to copy files between preview widgets, even if
they use different connections.
---------
Co-authored-by: Evan Simkowitz <esimkowitz@users.noreply.github.com>
I was dumb and used `os.Rename` for copy on the same WSH remote. This
change makes it a proper copy, with recursion if needed.
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>