Skip to content

Commit 8306c6b

Browse files
authored
remove orphaned style.scss, make windowtype.ts, small CSS cleanup (#2939)
also duplicates rules.md for kilocode which was not picking it up from the .roo directory
1 parent ba7aea7 commit 8306c6b

19 files changed

Lines changed: 507 additions & 282 deletions

File tree

.kilocode/rules/overview.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# Wave Terminal - High Level Architecture Overview
2+
3+
## Project Description
4+
5+
Wave Terminal is an open-source AI-native terminal built for seamless workflows. It's an Electron application that serves as a command line terminal host (it hosts CLI applications rather than running inside a CLI). The application combines a React frontend with a Go backend server to provide a modern terminal experience with advanced features.
6+
7+
## Top-Level Directory Structure
8+
9+
```
10+
waveterm/
11+
├── emain/ # Electron main process code
12+
├── frontend/ # React application (renderer process)
13+
├── cmd/ # Go command-line applications
14+
├── pkg/ # Go packages/modules
15+
├── db/ # Database migrations
16+
├── docs/ # Documentation (Docusaurus)
17+
├── build/ # Build configuration and assets
18+
├── assets/ # Application assets (icons, images)
19+
├── public/ # Static public assets
20+
├── tests/ # Test files
21+
├── .github/ # GitHub workflows and configuration
22+
└── Configuration files (package.json, tsconfig.json, etc.)
23+
```
24+
25+
## Architecture Components
26+
27+
### 1. Electron Main Process (`emain/`)
28+
29+
The Electron main process handles the native desktop application layer:
30+
31+
**Key Files:**
32+
33+
- [`emain.ts`](emain/emain.ts) - Main entry point, application lifecycle management
34+
- [`emain-window.ts`](emain/emain-window.ts) - Window management (`WaveBrowserWindow` class)
35+
- [`emain-tabview.ts`](emain/emain-tabview.ts) - Tab view management (`WaveTabView` class)
36+
- [`emain-wavesrv.ts`](emain/emain-wavesrv.ts) - Go backend server integration
37+
- [`emain-wsh.ts`](emain/emain-wsh.ts) - WSH (Wave Shell) client integration
38+
- [`emain-ipc.ts`](emain/emain-ipc.ts) - IPC handlers for frontend ↔ main process communication
39+
- [`emain-menu.ts`](emain/emain-menu.ts) - Application menu system
40+
- [`updater.ts`](emain/updater.ts) - Auto-update functionality
41+
- [`preload.ts`](emain/preload.ts) - Preload script for renderer security
42+
- [`preload-webview.ts`](emain/preload-webview.ts) - Webview preload script
43+
44+
### 2. Frontend React Application (`frontend/`)
45+
46+
The React application runs in the Electron renderer process:
47+
48+
**Structure:**
49+
50+
```
51+
frontend/
52+
├── app/ # Main application code
53+
│ ├── app.tsx # Root App component
54+
│ ├── aipanel/ # AI panel UI
55+
│ ├── block/ # Block-based UI components
56+
│ ├── element/ # Reusable UI elements
57+
│ ├── hook/ # Custom React hooks
58+
│ ├── modals/ # Modal components
59+
│ ├── store/ # State management (Jotai)
60+
│ ├── tab/ # Tab components
61+
│ ├── view/ # Different view types
62+
│ │ ├── codeeditor/ # Code editor (Monaco)
63+
│ │ ├── preview/ # File preview
64+
│ │ ├── sysinfo/ # System info view
65+
│ │ ├── term/ # Terminal view
66+
│ │ ├── tsunami/ # Tsunami builder view
67+
│ │ ├── vdom/ # Virtual DOM view
68+
│ │ ├── waveai/ # AI chat integration
69+
│ │ ├── waveconfig/ # Config editor view
70+
│ │ └── webview/ # Web view
71+
│ └── workspace/ # Workspace management
72+
├── builder/ # Builder app entry
73+
├── layout/ # Layout system
74+
├── preview/ # Standalone preview renderer
75+
├── types/ # TypeScript type definitions
76+
└── util/ # Utility functions
77+
```
78+
79+
**Key Technologies:**
80+
81+
- Electron (desktop application shell)
82+
- React 19 with TypeScript
83+
- Jotai for state management
84+
- Monaco Editor for code editing
85+
- XTerm.js for terminal emulation
86+
- Tailwind CSS v4 for styling
87+
- SCSS for additional styling (deprecated, new components should use Tailwind)
88+
- Vite / electron-vite for bundling
89+
- Task (Taskfile.yml) for build and code generation commands
90+
91+
### 3. Go Backend Server (`cmd/server/`)
92+
93+
The Go backend server handles all heavy lifting operations:
94+
95+
**Entry Point:** [`main-server.go`](cmd/server/main-server.go)
96+
97+
### 4. Go Packages (`pkg/`)
98+
99+
The Go codebase is organized into modular packages:
100+
101+
**Key Packages:**
102+
103+
- `wstore/` - Database and storage layer
104+
- `wconfig/` - Configuration management
105+
- `wcore/` - Core business logic
106+
- `wshrpc/` - RPC communication system
107+
- `wshutil/` - WSH (Wave Shell) utilities
108+
- `blockcontroller/` - Block execution management
109+
- `remote/` - Remote connection handling
110+
- `filestore/` - File storage system
111+
- `web/` - Web server and WebSocket handling
112+
- `telemetry/` - Usage analytics and telemetry
113+
- `waveobj/` - Core data objects
114+
- `service/` - Service layer
115+
- `wps/` - Wave PubSub event system
116+
- `waveai/` - AI functionality
117+
- `shellexec/` - Shell execution
118+
- `util/` - Common utilities
119+
120+
### 5. Command Line Tools (`cmd/`)
121+
122+
Key Go command-line utilities:
123+
124+
- `wsh/` - Wave Shell command-line tool
125+
- `server/` - Main backend server
126+
- `generatego/` - Code generation
127+
- `generateschema/` - Schema generation
128+
- `generatets/` - TypeScript generation
129+
130+
## Communication Architecture
131+
132+
The core communication system is built around the **WSH RPC (Wave Shell RPC)** system, which provides a unified interface for all inter-process communication: frontend ↔ Go backend, Electron main process ↔ backend, and backend ↔ remote systems (SSH, WSL).
133+
134+
### WSH RPC System (`pkg/wshrpc/`)
135+
136+
The WSH RPC system is the backbone of Wave Terminal's communication architecture:
137+
138+
**Key Components:**
139+
140+
- [`wshrpctypes.go`](pkg/wshrpc/wshrpctypes.go) - Core RPC interface and type definitions (source of truth for all RPC commands)
141+
- [`wshserver/`](pkg/wshrpc/wshserver/) - Server-side RPC implementation
142+
- [`wshremote/`](pkg/wshrpc/wshremote/) - Remote connection handling
143+
- [`wshclient.go`](pkg/wshrpc/wshclient.go) - Go client for making RPC calls
144+
- [`frontend/app/store/wshclientapi.ts`](frontend/app/store/wshclientapi.ts) - Generated TypeScript RPC client
145+
146+
**Routing:** Callers address RPC calls using _routes_ (e.g. a block ID, connection name, or `"waveapp"`) rather than caring about the underlying transport. The RPC layer resolves the route to the correct transport (WebSocket, Unix socket, SSH tunnel, stdio) automatically. This means the same RPC interface works whether the target is local or a remote SSH connection.
147+
148+
## Development Notes
149+
150+
- **Build commands** - Use `task` (Taskfile.yml) for all build, generate, and packaging commands
151+
- **Code generation** - Run `task generate` after modifying Go types in `pkg/wshrpc/wshrpctypes.go`, `pkg/wconfig/settingsconfig.go`, or `pkg/waveobj/wtypemeta.go`
152+
- **Testing** - Vitest for frontend unit tests; standard `go test` for Go packages
153+
- **Database migrations** - SQL migration files in `db/migrations-wstore/` and `db/migrations-filestore/`
154+
- **Documentation** - Docusaurus site in `docs/`

.kilocode/rules/rules.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
Wave Terminal is a modern terminal which provides graphical blocks, dynamic layout, workspaces, and SSH connection management. It is cross platform and built on electron.
2+
3+
### Project Structure
4+
5+
It has a TypeScript/React frontend and a Go backend. They talk together over `wshrpc` a custom RPC protocol that is implemented over websocket (and domain sockets).
6+
7+
### Coding Guidelines
8+
9+
- **Go Conventions**:
10+
- Don't use custom enum types in Go. Instead, use string constants (e.g., `const StatusRunning = "running"` rather than creating a custom type like `type Status string`).
11+
- Use string constants for status values, packet types, and other string-based enumerations.
12+
- in Go code, prefer using Printf() vs Println()
13+
- use "Make" as opposed to "New" for struct initialization func names
14+
- in general const decls go at the top of the file (before types and functions)
15+
- NEVER run `go build` (especially in weird sub-package directories). we can tell if everything compiles by seeing there are no problems/errors.
16+
- **Synchronization**:
17+
- Always prefer to use the `lock.Lock(); defer lock.Unlock()` pattern for synchronization if possible
18+
- Avoid inline lock/unlock pairs - instead create helper functions that use the defer pattern
19+
- When accessing shared data structures (maps, slices, etc.), ensure proper locking
20+
- Example: Instead of `gc.lock.Lock(); gc.map[key]++; gc.lock.Unlock()`, create a helper function like `getNextValue(key string) int { gc.lock.Lock(); defer gc.lock.Unlock(); gc.map[key]++; return gc.map[key] }`
21+
- **TypeScript Imports**:
22+
- Use `@/...` for imports from different parts of the project (configured in `tsconfig.json` as `"@/*": ["frontend/*"]`).
23+
- Prefer relative imports (`"./name"`) only within the same directory.
24+
- Use named exports exclusively; avoid default exports. It's acceptable to export functions directly (e.g., React Components).
25+
- Our indent is 4 spaces
26+
- **JSON Field Naming**: All fields must be lowercase, without underscores.
27+
- **TypeScript Conventions**
28+
- **Type Handling**:
29+
- In TypeScript we have strict null checks off, so no need to add "| null" to all the types.
30+
- In TypeScript for Jotai atoms, if we want to write, we need to type the atom as a PrimitiveAtom<Type>
31+
- Jotai has a bug with strict null checks off where if you create a null atom, e.g. atom(null) it does not "type" correctly. That's no issue, just cast it to the proper PrimitiveAtom type (no "| null") and it will work fine.
32+
- Generally never use "=== undefined" or "!== undefined". This is bad style. Just use a "== null" or "!= null" unless it is a very specific case where we need to distinguish undefined from null.
33+
- **Coding Style**:
34+
- Use all lowercase filenames (except where case is actually important like Taskfile.yml)
35+
- Import the "cn" function from "@/util/util" to do classname / clsx class merge (it uses twMerge underneath)
36+
- For element variants use class-variance-authority
37+
- Do NOT create private fields in classes (they are impossible to inspect)
38+
- Use PascalCase for global consts at the top of files
39+
- **Component Practices**:
40+
- Make sure to add cursor-pointer to buttons/links and clickable items
41+
- NEVER use cursor-help (it looks terrible)
42+
- useAtom() and useAtomValue() are react HOOKS, so they must be called at the component level not inline in JSX
43+
- If you use React.memo(), make sure to add a displayName for the component
44+
- Other
45+
- never use atob() or btoa() (not UTF-8 safe). use functions in frontend/util/util.ts for base64 decoding and encoding
46+
- In general, when writing functions, we prefer _early returns_ rather than putting the majority of a function inside of an if block.
47+
48+
### Styling
49+
50+
- We use **Tailwind v4** to style. Custom stuff is defined in frontend/tailwindsetup.css
51+
- _never_ use cursor-help, or cursor-not-allowed (it looks terrible)
52+
- We have custom CSS setup as well, so it is a hybrid system. For new code we prefer tailwind, and are working to migrate code to all use tailwind.
53+
- For accent buttons, use "bg-accent/80 text-primary rounded hover:bg-accent transition-colors cursor-pointer" (if you do "bg-accent hover:bg-accent/80" it looks weird as on hover the button gets darker instead of lighter)
54+
55+
### RPC System
56+
57+
To define a new RPC call, add the new definition to `pkg/wshrpc/wshrpctypes.go` including any input/output data that is required. After modifying wshrpctypes.go run `task generate` to generate the client APIs.
58+
59+
For normal "server" RPCs (where a frontend client is calling the main server) you should implement the RPC call in `pkg/wshrpc/wshserver.go`.
60+
61+
### Electron API
62+
63+
From within the FE to get the electron API (e.g. the preload functions):
64+
65+
```ts
66+
import { getApi } from "@/store/global";
67+
68+
getApi().getIsDev();
69+
```
70+
71+
The full API is defined in custom.d.ts as type ElectronApi.
72+
73+
### Code Generation
74+
75+
- **TypeScript Types**: TypeScript types are automatically generated from Go types. After modifying Go types in `pkg/wshrpc/wshrpctypes.go`, run `task generate` to update the TypeScript type definitions in `frontend/types/gotypes.d.ts`.
76+
- **Manual Edits**: Do not manually edit generated files like `frontend/types/gotypes.d.ts` or `frontend/app/store/wshclientapi.ts`. Instead, modify the source Go types and run `task generate`.
77+
78+
### Frontend Architecture
79+
80+
- The application uses Jotai for state management.
81+
- When working with Jotai atoms that need to be updated, define them as `PrimitiveAtom<Type>` rather than just `atom<Type>`.
82+
83+
### Notes
84+
85+
- **CRITICAL: Completion format MUST be: "Done: [one-line description]"**
86+
- **Keep your Task Completed summaries VERY short**
87+
- **No lengthy pre-completion summaries** - Do not provide detailed explanations of implementation before using attempt_completion
88+
- **No recaps of changes** - Skip explaining what was done before completion
89+
- **Go directly to completion** - After making changes, proceed directly to attempt_completion without summarizing
90+
- The project is currently an un-released POC / MVP. Do not worry about backward compatibility when making changes
91+
- With React hooks, always complete all hook calls at the top level before any conditional returns (including jotai hook calls useAtom and useAtomValue); when a user explicitly tells you a function handles null inputs, trust them and stop trying to "protect" it with unnecessary checks or workarounds.
92+
- **Match response length to question complexity** - For simple, direct questions in Ask mode (especially those that can be answered in 1-2 sentences), provide equally brief answers. Save detailed explanations for complex topics or when explicitly requested.
93+
- **CRITICAL** - useAtomValue and useAtom are React HOOKS. They cannot be used inline in JSX code, they must appear at the top of a component in the hooks area of the react code.
94+
- for simple functions, we prefer `if (!cond) { return }; functionality;` pattern over `if (cond) { functionality }` because it produces less indentation and is easier to follow.
95+
- It is now 2026, so if you write new files, or update files use 2026 for the copyright year
96+
- React.MutableRefObject is deprecated, just use React.RefObject now (in React 19 RefObject is always mutable)
97+
98+
### Strict Comment Rules
99+
100+
- **NEVER add comments that merely describe what code is doing**:
101+
-`mutex.Lock() // Lock the mutex`
102+
-`counter++ // Increment the counter`
103+
-`buffer.Write(data) // Write data to buffer`
104+
-`// Header component for app run list` (above AppRunListHeader)
105+
-`// Updated function to include onClick parameter`
106+
-`// Changed padding calculation`
107+
-`// Removed unnecessary div`
108+
-`// Using the model's width value here`
109+
- **Only use comments for**:
110+
- Explaining WHY a particular approach was chosen
111+
- Documenting non-obvious edge cases or side effects
112+
- Warning about potential pitfalls in usage
113+
- Explaining complex algorithms that can't be simplified
114+
- **When in doubt, leave it out**. No comment is better than a redundant comment.
115+
- **Never add comments explaining code changes** - The code should speak for itself, and version control tracks changes. The one exception to this rule is if it is a very unobvious implementation. Something that someone would typically implement in a different (wrong) way. Then the comment helps us remember WHY we changed it to a less obvious implementation.
116+
- **Never remove existing comments** unless specifically directed by the user. Comments that are already defined in existing code have been vetted by the user.
117+
118+
### Jotai Model Pattern (our rules)
119+
120+
- **Atoms live on the model.**
121+
- **Simple atoms:** define as **field initializers**.
122+
- **Atoms that depend on values/other atoms:** create in the **constructor**.
123+
- Models **never use React hooks**; they use `globalStore.get/set`.
124+
- It's fine to call model methods from **event handlers** or **`useEffect`**.
125+
- Models use the **singleton pattern** with a `private static instance` field, a `private constructor`, and a `static getInstance()` method.
126+
- The constructor is `private`; callers always use `getInstance()`.
127+
128+
```ts
129+
// model/MyModel.ts
130+
import * as jotai from "jotai";
131+
import { globalStore } from "@/app/store/jotaiStore";
132+
133+
export class MyModel {
134+
private static instance: MyModel | null = null;
135+
136+
// simple atoms (field init)
137+
statusAtom = jotai.atom<"idle" | "running" | "error">("idle");
138+
outputAtom = jotai.atom("");
139+
140+
// ctor-built atoms (need types)
141+
lengthAtom!: jotai.Atom<number>;
142+
thresholdedAtom!: jotai.Atom<boolean>;
143+
144+
private constructor(initialThreshold = 20) {
145+
this.lengthAtom = jotai.atom((get) => get(this.outputAtom).length);
146+
this.thresholdedAtom = jotai.atom((get) => get(this.lengthAtom) > initialThreshold);
147+
}
148+
149+
static getInstance(): MyModel {
150+
if (!MyModel.instance) {
151+
MyModel.instance = new MyModel();
152+
}
153+
return MyModel.instance;
154+
}
155+
156+
static resetInstance(): void {
157+
MyModel.instance = null;
158+
}
159+
160+
async doWork() {
161+
globalStore.set(this.statusAtom, "running");
162+
// ... do work ...
163+
globalStore.set(this.statusAtom, "idle");
164+
}
165+
}
166+
```
167+
168+
```tsx
169+
// component usage (events & effects OK)
170+
import { useAtomValue } from "jotai";
171+
172+
function Panel() {
173+
const model = MyModel.getInstance();
174+
const status = useAtomValue(model.statusAtom);
175+
const isBig = useAtomValue(model.thresholdedAtom);
176+
177+
const onClick = () => model.doWork();
178+
179+
return (
180+
<div>
181+
{status}{String(isBig)}
182+
</div>
183+
);
184+
}
185+
```
186+
187+
**Remember:** singleton pattern with `getInstance()`, `private constructor`, atoms on the model, simple-as-fields, ctor for dependent/derived, updates via `globalStore.set/get`.
188+
**Note** Older models may not use the singleton pattern
189+
190+
### Tool Use
191+
192+
Do NOT use write_to_file unless it is a new file or very short. Always prefer to use replace_in_file. Often your diffs fail when a file may be out of date in your cache vs the actual on-disk format. You should RE-READ the file and try to create diffs again if your diffs fail rather than fall back to write_to_file. If you feel like your ONLY option is to use write_to_file please ask first.
193+
194+
Also when adding content to the end of files prefer to use the new append_file tool rather than trying to create a diff (as your diffs are often not specific enough and end up inserting code in the middle of existing functions).
195+
196+
### Directory Awareness
197+
198+
- **ALWAYS verify the current working directory before executing commands**
199+
- Either run "pwd" first to verify the directory, or do a "cd" to the correct absolute directory before running commands
200+
- When running tests, do not "cd" to the pkg directory and then run the test. This screws up the cwd and you never recover. run the test from the project root instead.
201+
202+
### Testing / Compiling Go Code
203+
204+
No need to run a `go build` or a `go run` to just check if the Go code compiles. VSCode's errors/problems cover this well.
205+
If there are no Go errors in VSCode you can assume the code compiles fine.

0 commit comments

Comments
 (0)