Skip to content

Commit c222b41

Browse files
wilcorreaCopilot
andauthored
Feature/copilot chat integration (#28)
* feat(chat): improve message types, session list layout and error feedback - Add message type support (agent_message_chunk vs agent_thought_chunk) - Apply CSS classes based on ACP message types - Render all assistant messages with markdown - Improve session list layout (title + plan button on same row) - Add visual error feedback for missing files (toast notification) - Remove emoji from plan button * feat(copilot-server): add standalone WebSocket server for ACP integration Move copilot server from examples/ to apps/copilot-server/ as a properly versioned component: - WebSocket server on port 8765 - ACP integration with GitHub Copilot CLI - Session management (list, load, resume) - Mode switching (ask/plan/autopilot) - Streaming responses with chunk types - Auto-approval of permissions Includes: - package.json with dependencies - README.md with protocol documentation - .gitignore for node_modules * feat(chat): add home directory command and UI mode improvements - Add get_home_dir Tauri command for accessing user home directory - Hide "Ask" mode button (Plan and Execute modes sufficient) - Rename "Autopilot" to "Execute" for clearer UX * poc: copilot cli up * docs: rewrite README to reflect React/TS stack and ACP integration - Update tagline and tech stack (React 18 + TypeScript + Vite + shadcn/ui) - Add GitHub Copilot / ACP integration section with modes table - Add multi-window architecture overview - Add plan workflow and session management documentation - Update comments section: SQLite instead of JSON sidecar files - Add dual IPC transport (Unix socket + TCP) - Update architecture table with all Rust modules - Fix development section: React/TS build, Vitest tests - Update contributing guidelines for new stack conventions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * style(icons): update app icons with new branding * refactor(frontend): remove old vanilla JS frontend * feat(frontend): migrate to React/TypeScript with Vite * feat(backend): add ACP, sessions, comments, and plan modules * test: add component and hook tests * docs: update project documentation for React/ACP stack * chore: remove legacy src-vanilla directory * chore: add memories to claude * feat: review session UI --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 6802367 commit c222b41

214 files changed

Lines changed: 24559 additions & 4584 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# React Conventions
2+
3+
## Component Structure
4+
5+
```
6+
src/components/
7+
├── ui/ # shadcn/ui primitives (47 components, auto-generated)
8+
├── settings/ # Settings window components
9+
│ ├── GeneralSettings.tsx # Theme + language selection
10+
│ └── WhisperSettings.tsx # Model download + config
11+
└── *.tsx # App-level components (21 files)
12+
```
13+
14+
**Naming:** PascalCase filenames matching export name. One component per file.
15+
16+
**Key components by feature:**
17+
- **Markdown viewer:** MarkdownViewer, OutlineSidebar, CommentCard, ReviewPanel
18+
- **Home/workspace:** HomeScreen, WorkspaceCard, DirectoryWorkspace, ActiveSessionView
19+
- **ACP chat:** TerminalChat, TerminalInput, TerminalMessage, ChatPanel, PlanPanel
20+
- **Sessions:** SessionCard, NewSessionForm
21+
- **Shared:** TopBar, StatusBar, ErrorBoundary, ErrorConsole, LoadingSpinner, MicButton
22+
23+
## Custom Hooks (6)
24+
25+
| Hook | Purpose | Tauri Commands |
26+
|------|---------|----------------|
27+
| `useAcpConnection` | Connect/disconnect ACP lifecycle | `acp_connect`, `acp_disconnect` |
28+
| `useAcpSession` | Message streaming, mode switching | `acp_send_prompt`, `acp_set_mode`, `acp_cancel` |
29+
| `useComments` | Block-based comment system | `hash_file`, `load_comments`, `save_comments` |
30+
| `useKeyboardShortcuts` | Register keyboard shortcuts | (none — DOM events) |
31+
| `useLocalSessions` | Session CRUD for workspace | `session_list`, `session_create`, `session_delete` |
32+
| `usePlanWorkflow` | Plan phase transitions | `session_update_plan_file_path`, `session_update_phase`, `plan_path` |
33+
34+
## Context (AppContext)
35+
36+
Single context providing global state:
37+
- `view`: 'home' | 'file-expanded' | 'directory-expanded'
38+
- `workspaces`: Workspace[] (persisted to localStorage `arandu:workspaces`)
39+
- `expandedWorkspaceId`: string | null
40+
- Operations: `openFile()`, `openDirectory()`, `expandWorkspace()`, `minimizeWorkspace()`, `closeWorkspace()`
41+
- File dialog integration via `window.__TAURI__.dialog.open()`
42+
- History tracking via `add_to_history` Tauri command
43+
44+
## shadcn/ui Usage
45+
46+
- Install: `npx shadcn@latest add <component>` (from `apps/tauri/` directory)
47+
- Components go to `src/components/ui/` (auto-generated, don't manually create)
48+
- Built on Radix UI primitives
49+
- Styling via TailwindCSS + CSS variables
50+
- Class merging: `cn()` from `@/lib/utils`
51+
- 47 components installed: accordion, alert, badge, button, card, dialog, dropdown-menu, input, label, popover, scroll-area, select, separator, sheet, sidebar, skeleton, slider, switch, table, tabs, textarea, toast, tooltip, etc.
52+
53+
## Tauri Integration Patterns
54+
55+
**Calling commands:**
56+
```typescript
57+
const result = await window.__TAURI__.core.invoke('command_name', { arg1: 'value' })
58+
```
59+
60+
**Listening to events:**
61+
```typescript
62+
useEffect(() => {
63+
const unlisten = window.__TAURI__.event.listen('event-name', (event) => {
64+
// handle event.payload
65+
})
66+
return () => { unlisten.then(fn => fn()) }
67+
}, [])
68+
```
69+
70+
**Window management:**
71+
```typescript
72+
const currentWindow = window.__TAURI__.window.getCurrentWindow()
73+
await currentWindow.hide()
74+
await currentWindow.show()
75+
```
76+
77+
**Type declarations** in `vite-env.d.ts` provide types for `window.__TAURI__`.
78+
79+
## Testing
80+
81+
**Framework:** Vitest + React Testing Library
82+
83+
**File layout:**
84+
```
85+
src/__tests__/
86+
├── setup.ts # Global setup (Tauri mocks)
87+
├── components/ # Component tests (*. test.tsx)
88+
│ ├── TopBar.test.tsx
89+
│ ├── HomeScreen.test.tsx
90+
│ ├── MarkdownViewer.test.tsx
91+
│ ├── ChatPanel.test.tsx
92+
│ └── ... (10 test files)
93+
└── hooks/ # Hook tests (*.test.ts)
94+
├── useComments.test.ts
95+
└── useKeyboardShortcuts.test.ts
96+
```
97+
98+
**Tauri mocking:** `setup.ts` provides mock `window.__TAURI__` with default implementations.
99+
Override per-test with `vi.mocked()`.
100+
101+
## TypeScript Types
102+
103+
**`types/index.ts`:** Workspace, Heading, Session, Message, Comment, CommentsData, PlanPhase, SessionRecord, SessionTab
104+
105+
**`types/acp.ts`:** AcpSessionMode, AcpSessionModeState, AcpSessionInfo, AcpSessionSummary, AcpSessionUpdate, AcpMessage
106+
107+
## Utility Libraries
108+
109+
| File | Export | Purpose |
110+
|------|--------|---------|
111+
| `lib/utils.ts` | `cn()` | Tailwind class merging (clsx + tailwind-merge) |
112+
| `lib/i18n.ts` | default i18n | i18next init, cross-window sync |
113+
| `lib/tray-sync.ts` | `updateTrayLabels()` | Sync tray menu with language |
114+
| `lib/format-path.ts` | `shortenPath()`, `initHomeDir()` | Path display with ~ |
115+
| `lib/block-utils.ts` | `blockLabel()`, `scrollToBlock()` | Comment block utilities |
116+
| `lib/date-locale.ts` | `getDateLocale()` | date-fns locale mapping |

.claude/memory/tauri-patterns.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Tauri Patterns & Gotchas
2+
3+
## Tauri Command Registration Flow
4+
5+
1. Define `#[tauri::command]` function in Rust module
6+
2. Register in `lib.rs``.invoke_handler(tauri::generate_handler![...])` (around line 618)
7+
3. Add permissions in `src-tauri/capabilities/default.json` if needed
8+
4. Call from JS: `window.__TAURI__.core.invoke('command_name', { args })`
9+
10+
Commands in submodules need `use crate::module::command_name;` import.
11+
12+
## Multi-Window Setup
13+
14+
**Vite entry points** (`vite.config.ts`):
15+
```
16+
rollupOptions.input = { main: index.html, settings: settings.html, whisper: whisper.html }
17+
```
18+
19+
**Window definitions** (`tauri.conf.json``app.windows`):
20+
- `main`: titleBarStyle "Overlay", hiddenTitle, visible false on startup
21+
- `settings`: 600x520, center, visible false (shown via `show_settings_window`)
22+
- `whisper`: 600x160, alwaysOnTop, no decorations, transparent, visible false
23+
24+
**Capabilities** (`capabilities/default.json`):
25+
- `windows: ["main", "whisper", "settings"]` — all three must be listed
26+
- Permissions include: core, cli, dialog, fs, updater, global-shortcut, clipboard-manager, window-state
27+
28+
## Cross-Window Communication
29+
30+
- **Language sync**: localStorage key `arandu-language`, `storage` event listener in `lib/i18n.ts`
31+
- **Tauri events**: Rust → JS via `app.emit("event-name", payload)`, listened with `window.__TAURI__.event.listen()`
32+
- **Window management**: Settings/whisper hide on close, re-shown with `show_settings_window`/`show_whisper_window` commands
33+
34+
## System Tray
35+
36+
- Custom "A" glyph rendered procedurally in Rust (SDF math, 36x36 RGBA)
37+
- macOS: `icon_as_template(true)` for system appearance integration
38+
- Menu items: Show Window, Record (with shortcut label), Settings, Quit
39+
- Labels update dynamically for i18n via `update_tray_labels` command
40+
- Left-click → show main window
41+
- Record toggle → emits events + manages recording state
42+
43+
## File Watching
44+
45+
- Uses `notify` crate (recommended_watcher)
46+
- `watch_file(path)` → canonicalizes path, registers with watcher
47+
- `unwatch_file(path)` → removes from watcher
48+
- Emits `file-changed` event to frontend on modification
49+
- De-duplicates by canonical path
50+
51+
## SQLite Persistence
52+
53+
**Database:** `{app_data_dir}/comments.db` with WAL mode
54+
55+
**Tables:**
56+
- `comments`: id, file_path, block_ids (JSON array), text, timestamp, resolved
57+
- `file_hashes`: file_path, file_hash (SHA256 for staleness detection)
58+
- `sessions`: id, workspace_path, acp_session_id, name, initial_prompt, plan_markdown, plan_file_path, phase, created_at, updated_at
59+
60+
**Migrations:** `init_sessions_table()` adds `plan_file_path` column if missing. Legacy `.comments.json` files auto-migrated to DB.
61+
62+
**State:** `CommentsDb(Mutex<Connection>)` managed as Tauri state, shared by comments and sessions modules.
63+
64+
## IPC Architecture
65+
66+
Two transports sharing `ipc_common.rs`:
67+
- **Unix socket** (`ipc.rs`): `~/.arandu/arandu.sock`, `#[cfg(unix)]`, Tokio async
68+
- **TCP server** (`tcp_ipc.rs`): `127.0.0.1:7474`, all platforms
69+
- JSON protocol, commands: open, ping, show
70+
- Graceful cleanup on quit, non-blocking on failure
71+
72+
## App Lifecycle
73+
74+
- Window close → hide (not quit), tray stays active
75+
- ExplicitQuit flag → clean up IPC/ACP connections → `exit(0)`
76+
- macOS Reopen event → show main window
77+
- Single instance plugin → second instance focuses existing window
78+
- CLI args (`--file`) → stored in `InitialFile` state → consumed by `get_initial_file` command
79+
- macOS file association click → `Opened` event → emits `open-file` to frontend
80+
81+
## Conditional Compilation
82+
83+
- `#[cfg(target_os = "macos")]`: cli_installer, app menu, Opened events
84+
- `#[cfg(unix)]`: IPC socket server
85+
- `#[cfg_attr(mobile, tauri::mobile_entry_point)]`: mobile support marker
86+
- Commands using conditional modules must also be conditionally registered in invoke_handler
87+
88+
## Plugins (8 total)
89+
90+
cli, dialog, fs, updater, global-shortcut, clipboard-manager, window-state, single-instance
91+
92+
Window-state plugin excludes "whisper" and "settings" windows from state persistence.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ playground.xcworkspace
7474
# Rust / Tauri
7575
apps/tauri/src-tauri/target/
7676
apps/tauri/src-tauri/gen/
77+
apps/tauri/coverage/
7778

7879
# Node
7980
node_modules/

.repo_ignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# RepoPrompt global ignore defaults (v2)
2+
**/node_modules/
3+
**/.npm/
4+
**/.pnpm-store/
5+
**/.yarn/
6+
**/.cache/
7+
**/bower_components/
8+
9+
**/__pycache__/
10+
**/.pytest_cache/
11+
**/.mypy_cache/
12+
13+
**/.gradle/
14+
**/.m2/
15+
**/.nuget/
16+
**/.cargo/
17+
**/.stack-work/
18+
**/.ccache/
19+
20+
**/.idea/
21+
**/.vscode/
22+
**/.bundle/
23+
**/.gem/
24+
25+
# Virtual environments
26+
**/.venv/
27+
**/venv/
28+
29+
# Common temp/junk files
30+
**/*.swp
31+
**/*~
32+
**/*.tmp
33+
**/*.temp
34+
**/*.bak

0 commit comments

Comments
 (0)