copilot-liku-cli 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +411 -0
- package/CONFIGURATION.md +302 -0
- package/CONTRIBUTING.md +225 -0
- package/ELECTRON_README.md +121 -0
- package/INSTALLATION.md +350 -0
- package/LICENSE.md +1 -0
- package/PROJECT_STATUS.md +229 -0
- package/QUICKSTART.md +255 -0
- package/README.md +167 -0
- package/TESTING.md +274 -0
- package/package.json +61 -0
- package/scripts/start.js +30 -0
- package/src/assets/tray-icon.png +0 -0
- package/src/cli/commands/agent.js +327 -0
- package/src/cli/commands/click.js +108 -0
- package/src/cli/commands/drag.js +85 -0
- package/src/cli/commands/find.js +109 -0
- package/src/cli/commands/keys.js +132 -0
- package/src/cli/commands/mouse.js +79 -0
- package/src/cli/commands/repl.js +290 -0
- package/src/cli/commands/screenshot.js +72 -0
- package/src/cli/commands/scroll.js +74 -0
- package/src/cli/commands/start.js +67 -0
- package/src/cli/commands/type.js +57 -0
- package/src/cli/commands/wait.js +84 -0
- package/src/cli/commands/window.js +104 -0
- package/src/cli/liku.js +249 -0
- package/src/cli/util/output.js +174 -0
- package/src/main/agents/base-agent.js +410 -0
- package/src/main/agents/builder.js +484 -0
- package/src/main/agents/index.js +62 -0
- package/src/main/agents/orchestrator.js +362 -0
- package/src/main/agents/researcher.js +511 -0
- package/src/main/agents/state-manager.js +344 -0
- package/src/main/agents/supervisor.js +365 -0
- package/src/main/agents/verifier.js +452 -0
- package/src/main/ai-service.js +1633 -0
- package/src/main/index.js +2208 -0
- package/src/main/inspect-service.js +467 -0
- package/src/main/system-automation.js +1186 -0
- package/src/main/ui-automation/config.js +76 -0
- package/src/main/ui-automation/core/helpers.js +41 -0
- package/src/main/ui-automation/core/index.js +15 -0
- package/src/main/ui-automation/core/powershell.js +82 -0
- package/src/main/ui-automation/elements/finder.js +274 -0
- package/src/main/ui-automation/elements/index.js +14 -0
- package/src/main/ui-automation/elements/wait.js +66 -0
- package/src/main/ui-automation/index.js +164 -0
- package/src/main/ui-automation/interactions/element-click.js +211 -0
- package/src/main/ui-automation/interactions/high-level.js +230 -0
- package/src/main/ui-automation/interactions/index.js +47 -0
- package/src/main/ui-automation/keyboard/index.js +15 -0
- package/src/main/ui-automation/keyboard/input.js +179 -0
- package/src/main/ui-automation/mouse/click.js +186 -0
- package/src/main/ui-automation/mouse/drag.js +88 -0
- package/src/main/ui-automation/mouse/index.js +30 -0
- package/src/main/ui-automation/mouse/movement.js +51 -0
- package/src/main/ui-automation/mouse/scroll.js +116 -0
- package/src/main/ui-automation/screenshot.js +183 -0
- package/src/main/ui-automation/window/index.js +23 -0
- package/src/main/ui-automation/window/manager.js +305 -0
- package/src/main/utils/time.js +62 -0
- package/src/main/visual-awareness.js +597 -0
- package/src/renderer/chat/chat.js +671 -0
- package/src/renderer/chat/index.html +725 -0
- package/src/renderer/chat/preload.js +112 -0
- package/src/renderer/overlay/index.html +648 -0
- package/src/renderer/overlay/overlay.js +782 -0
- package/src/renderer/overlay/preload.js +90 -0
- package/src/shared/grid-math.js +82 -0
- package/src/shared/inspect-types.js +230 -0
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# Architecture Documentation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This application implements an Electron-based headless agent system with an ultra-thin overlay architecture. The design prioritizes minimal resource usage, non-intrusive UI, and extensible agent integration.
|
|
6
|
+
|
|
7
|
+
## Design Principles
|
|
8
|
+
|
|
9
|
+
1. **Minimal Footprint**: Single main process, lightweight renderers, no heavy frameworks
|
|
10
|
+
2. **Non-Intrusive**: Transparent overlay, edge-docked chat, never blocks user workspace
|
|
11
|
+
3. **Performance-First**: Click-through by default, minimal background processing
|
|
12
|
+
4. **Secure**: Context isolation, no Node integration in renderers, CSP headers
|
|
13
|
+
5. **Extensible**: Clean IPC message schema ready for agent integration
|
|
14
|
+
|
|
15
|
+
## System Architecture
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
19
|
+
│ Main Process │
|
|
20
|
+
│ ┌────────────┐ ┌──────────┐ ┌────────────┐ ┌─────────────┐ │
|
|
21
|
+
│ │ Overlay │ │ Chat │ │ Tray │ │ Global │ │
|
|
22
|
+
│ │ Manager │ │ Manager │ │ Icon │ │ Hotkeys │ │
|
|
23
|
+
│ └─────┬──────┘ └────┬─────┘ └─────┬──────┘ └──────┬──────┘ │
|
|
24
|
+
│ │ │ │ │ │
|
|
25
|
+
│ ┌─────┴──────────────┴──────────────┴────────────────┴──────┐ │
|
|
26
|
+
│ │ IPC Router │ │
|
|
27
|
+
│ └─────┬────────────────────────────────────────────┬────────┘ │
|
|
28
|
+
└────────┼────────────────────────────────────────────┼───────────┘
|
|
29
|
+
│ │
|
|
30
|
+
┌────┴────────┐ ┌───────┴────────┐
|
|
31
|
+
│ Overlay │ │ Chat │
|
|
32
|
+
│ Renderer │ │ Renderer │
|
|
33
|
+
│ │ │ │
|
|
34
|
+
│ ┌─────────┐ │ │ ┌────────────┐ │
|
|
35
|
+
│ │ Dots │ │ │ │ History │ │
|
|
36
|
+
│ │ Grid │ │ │ │ │ │
|
|
37
|
+
│ └─────────┘ │ │ └────────────┘ │
|
|
38
|
+
│ ┌─────────┐ │ │ ┌────────────┐ │
|
|
39
|
+
│ │ Mode │ │ │ │ Input │ │
|
|
40
|
+
│ │Indicator│ │ │ │ │ │
|
|
41
|
+
│ └─────────┘ │ │ └────────────┘ │
|
|
42
|
+
└─────────────┘ │ ┌────────────┐ │
|
|
43
|
+
│ │ Controls │ │
|
|
44
|
+
│ └────────────┘ │
|
|
45
|
+
└────────────────┘
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Component Details
|
|
49
|
+
|
|
50
|
+
### Main Process (`src/main/index.js`)
|
|
51
|
+
|
|
52
|
+
**Responsibilities:**
|
|
53
|
+
- Window lifecycle management
|
|
54
|
+
- IPC message routing
|
|
55
|
+
- Global state management
|
|
56
|
+
- System integration (tray, hotkeys)
|
|
57
|
+
|
|
58
|
+
**Key Functions:**
|
|
59
|
+
- `createOverlayWindow()`: Creates transparent, always-on-top overlay
|
|
60
|
+
- `createChatWindow()`: Creates edge-docked chat interface
|
|
61
|
+
- `createTray()`: Sets up system tray icon and menu
|
|
62
|
+
- `registerShortcuts()`: Registers global hotkeys
|
|
63
|
+
- `setupIPC()`: Configures IPC message handlers
|
|
64
|
+
- `setOverlayMode()`: Switches between passive/selection modes
|
|
65
|
+
- `toggleChat()`: Shows/hides chat window
|
|
66
|
+
- `toggleOverlay()`: Shows/hides overlay
|
|
67
|
+
|
|
68
|
+
**State:**
|
|
69
|
+
```javascript
|
|
70
|
+
{
|
|
71
|
+
overlayMode: 'passive' | 'selection',
|
|
72
|
+
isChatVisible: boolean,
|
|
73
|
+
overlayWindow: BrowserWindow,
|
|
74
|
+
chatWindow: BrowserWindow,
|
|
75
|
+
tray: Tray
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Overlay Renderer (`src/renderer/overlay/`)
|
|
80
|
+
|
|
81
|
+
**Responsibilities:**
|
|
82
|
+
- Render dot grid
|
|
83
|
+
- Handle dot interactions
|
|
84
|
+
- Display mode indicator
|
|
85
|
+
- Communicate selections to main process
|
|
86
|
+
|
|
87
|
+
**Files:**
|
|
88
|
+
- `index.html`: UI structure and styles
|
|
89
|
+
- `preload.js`: Secure IPC bridge
|
|
90
|
+
|
|
91
|
+
**State:**
|
|
92
|
+
```javascript
|
|
93
|
+
{
|
|
94
|
+
currentMode: 'passive' | 'selection',
|
|
95
|
+
gridType: 'coarse' | 'fine',
|
|
96
|
+
dots: Array<{id, x, y, label}>
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Key Functions:**
|
|
101
|
+
- `generateCoarseGrid()`: Creates 100px spacing grid
|
|
102
|
+
- `generateFineGrid()`: Creates 50px spacing grid
|
|
103
|
+
- `renderDots()`: Renders interactive dots
|
|
104
|
+
- `selectDot()`: Handles dot click events
|
|
105
|
+
- `updateModeDisplay()`: Updates UI based on mode
|
|
106
|
+
|
|
107
|
+
### Chat Renderer (`src/renderer/chat/`)
|
|
108
|
+
|
|
109
|
+
**Responsibilities:**
|
|
110
|
+
- Display chat history
|
|
111
|
+
- Handle user input
|
|
112
|
+
- Show mode controls
|
|
113
|
+
- Receive agent responses
|
|
114
|
+
|
|
115
|
+
**Files:**
|
|
116
|
+
- `index.html`: UI structure and styles
|
|
117
|
+
- `preload.js`: Secure IPC bridge
|
|
118
|
+
|
|
119
|
+
**State:**
|
|
120
|
+
```javascript
|
|
121
|
+
{
|
|
122
|
+
currentMode: 'passive' | 'selection',
|
|
123
|
+
messages: Array<{text, type, timestamp}>
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Key Functions:**
|
|
128
|
+
- `addMessage()`: Adds message to history
|
|
129
|
+
- `sendMessage()`: Sends user message to main
|
|
130
|
+
- `setMode()`: Changes overlay mode
|
|
131
|
+
- `updateModeDisplay()`: Updates mode button states
|
|
132
|
+
|
|
133
|
+
## IPC Message Schema
|
|
134
|
+
|
|
135
|
+
### Message Types
|
|
136
|
+
|
|
137
|
+
#### overlay → main → chat: dot-selected
|
|
138
|
+
```javascript
|
|
139
|
+
{
|
|
140
|
+
id: string, // e.g., 'dot-100-200'
|
|
141
|
+
x: number, // Screen X coordinate
|
|
142
|
+
y: number, // Screen Y coordinate
|
|
143
|
+
label: string, // e.g., 'A2'
|
|
144
|
+
timestamp: number // Unix timestamp in ms
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### chat → main → overlay: set-mode
|
|
149
|
+
```javascript
|
|
150
|
+
'passive' | 'selection'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
#### chat → main: chat-message
|
|
154
|
+
```javascript
|
|
155
|
+
string // User message text
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### main → chat: agent-response
|
|
159
|
+
```javascript
|
|
160
|
+
{
|
|
161
|
+
text: string, // Response text
|
|
162
|
+
timestamp: number // Unix timestamp in ms
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### main → overlay: mode-changed
|
|
167
|
+
```javascript
|
|
168
|
+
'passive' | 'selection'
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### renderer → main: get-state (invoke/handle)
|
|
172
|
+
```javascript
|
|
173
|
+
// Response:
|
|
174
|
+
{
|
|
175
|
+
overlayMode: 'passive' | 'selection',
|
|
176
|
+
isChatVisible: boolean
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Window Configuration
|
|
181
|
+
|
|
182
|
+
### Overlay Window
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
{
|
|
186
|
+
// Frameless and transparent
|
|
187
|
+
frame: false,
|
|
188
|
+
transparent: true,
|
|
189
|
+
|
|
190
|
+
// Always on top
|
|
191
|
+
alwaysOnTop: true,
|
|
192
|
+
level: 'screen-saver', // macOS only
|
|
193
|
+
|
|
194
|
+
// Full screen
|
|
195
|
+
fullscreen: true,
|
|
196
|
+
|
|
197
|
+
// Non-interactive by default
|
|
198
|
+
focusable: false,
|
|
199
|
+
skipTaskbar: true,
|
|
200
|
+
|
|
201
|
+
// Security
|
|
202
|
+
webPreferences: {
|
|
203
|
+
nodeIntegration: false,
|
|
204
|
+
contextIsolation: true,
|
|
205
|
+
preload: 'overlay/preload.js'
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Chat Window
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
{
|
|
214
|
+
// Standard window with frame
|
|
215
|
+
frame: true,
|
|
216
|
+
transparent: false,
|
|
217
|
+
|
|
218
|
+
// Positioned at bottom-right
|
|
219
|
+
x: width - chatWidth - margin,
|
|
220
|
+
y: height - chatHeight - margin,
|
|
221
|
+
|
|
222
|
+
// Resizable but not always on top
|
|
223
|
+
resizable: true,
|
|
224
|
+
alwaysOnTop: false,
|
|
225
|
+
|
|
226
|
+
// Hidden by default
|
|
227
|
+
show: false,
|
|
228
|
+
|
|
229
|
+
// Security
|
|
230
|
+
webPreferences: {
|
|
231
|
+
nodeIntegration: false,
|
|
232
|
+
contextIsolation: true,
|
|
233
|
+
preload: 'chat/preload.js'
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Mode System
|
|
239
|
+
|
|
240
|
+
### Passive Mode
|
|
241
|
+
- **Purpose**: Allow normal application interaction
|
|
242
|
+
- **Behavior**:
|
|
243
|
+
- Overlay fully click-through via `setIgnoreMouseEvents(true)`
|
|
244
|
+
- No dots rendered
|
|
245
|
+
- Mode indicator hidden
|
|
246
|
+
- CPU usage minimal (no event processing)
|
|
247
|
+
|
|
248
|
+
### Selection Mode
|
|
249
|
+
- **Purpose**: Enable screen element selection
|
|
250
|
+
- **Behavior**:
|
|
251
|
+
- Overlay captures mouse events via `setIgnoreMouseEvents(false)`
|
|
252
|
+
- Dots rendered with CSS `pointer-events: auto`
|
|
253
|
+
- Mode indicator visible
|
|
254
|
+
- Click events captured and routed via IPC
|
|
255
|
+
- Automatically reverts to passive after selection
|
|
256
|
+
|
|
257
|
+
## Security Architecture
|
|
258
|
+
|
|
259
|
+
### Context Isolation
|
|
260
|
+
All renderer processes use context isolation to prevent prototype pollution attacks.
|
|
261
|
+
|
|
262
|
+
### Preload Scripts
|
|
263
|
+
Secure bridge between main and renderer processes:
|
|
264
|
+
```javascript
|
|
265
|
+
contextBridge.exposeInMainWorld('electronAPI', {
|
|
266
|
+
// Only expose necessary methods
|
|
267
|
+
selectDot: (data) => ipcRenderer.send('dot-selected', data),
|
|
268
|
+
onModeChanged: (cb) => ipcRenderer.on('mode-changed', cb)
|
|
269
|
+
});
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Content Security Policy
|
|
273
|
+
All HTML files include CSP headers:
|
|
274
|
+
```html
|
|
275
|
+
<meta http-equiv="Content-Security-Policy"
|
|
276
|
+
content="default-src 'self'; style-src 'self' 'unsafe-inline';">
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### No Remote Content
|
|
280
|
+
All resources loaded locally, no CDN or external dependencies.
|
|
281
|
+
|
|
282
|
+
## Performance Characteristics
|
|
283
|
+
|
|
284
|
+
### Memory Usage
|
|
285
|
+
- **Target**: < 300MB steady-state
|
|
286
|
+
- **Baseline**: ~150MB for Electron + Chromium
|
|
287
|
+
- **Overlay**: ~20-30MB (minimal DOM, vanilla JS)
|
|
288
|
+
- **Chat**: ~30-40MB (simple UI, limited history)
|
|
289
|
+
|
|
290
|
+
### CPU Usage
|
|
291
|
+
- **Idle (passive mode)**: < 0.5%
|
|
292
|
+
- **Selection mode**: < 2%
|
|
293
|
+
- **During interaction**: < 5%
|
|
294
|
+
|
|
295
|
+
### Startup Time
|
|
296
|
+
- **Target**: < 3 seconds to functional
|
|
297
|
+
- **Breakdown**:
|
|
298
|
+
- Electron init: ~1s
|
|
299
|
+
- Window creation: ~1s
|
|
300
|
+
- Renderer load: ~0.5s
|
|
301
|
+
|
|
302
|
+
## Extensibility Points
|
|
303
|
+
|
|
304
|
+
### Agent Integration
|
|
305
|
+
Replace stub in `src/main/index.js`:
|
|
306
|
+
```javascript
|
|
307
|
+
ipcMain.on('chat-message', async (event, message) => {
|
|
308
|
+
// Call external agent API or worker process
|
|
309
|
+
const response = await agent.process(message);
|
|
310
|
+
chatWindow.webContents.send('agent-response', response);
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Custom Grid Patterns
|
|
315
|
+
Add to overlay renderer:
|
|
316
|
+
```javascript
|
|
317
|
+
function generateCustomGrid(pattern) {
|
|
318
|
+
// Implement custom dot placement logic
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Additional Windows
|
|
323
|
+
Follow pattern:
|
|
324
|
+
```javascript
|
|
325
|
+
function createSettingsWindow() {
|
|
326
|
+
settingsWindow = new BrowserWindow({
|
|
327
|
+
webPreferences: {
|
|
328
|
+
contextIsolation: true,
|
|
329
|
+
nodeIntegration: false,
|
|
330
|
+
preload: path.join(__dirname, 'preload.js')
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Plugin System (Future)
|
|
337
|
+
```javascript
|
|
338
|
+
// Example plugin interface
|
|
339
|
+
const plugin = {
|
|
340
|
+
name: 'screen-capture',
|
|
341
|
+
init: (mainProcess) => {
|
|
342
|
+
// Register IPC handlers
|
|
343
|
+
ipcMain.on('capture-screen', plugin.captureScreen);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Platform Differences
|
|
349
|
+
|
|
350
|
+
### macOS
|
|
351
|
+
- Window level: `'screen-saver'` to float above fullscreen
|
|
352
|
+
- Dock: Hidden via `app.dock.hide()`
|
|
353
|
+
- Tray: NSStatusBar with popover behavior
|
|
354
|
+
- Permissions: Requires accessibility + screen recording
|
|
355
|
+
|
|
356
|
+
### Windows
|
|
357
|
+
- Window level: Standard `alwaysOnTop`
|
|
358
|
+
- Taskbar: Overlay hidden via `skipTaskbar`
|
|
359
|
+
- Tray: System tray with balloon tooltips
|
|
360
|
+
- Permissions: No special permissions required
|
|
361
|
+
|
|
362
|
+
## Troubleshooting
|
|
363
|
+
|
|
364
|
+
### Overlay Not Appearing
|
|
365
|
+
1. Check window level setting
|
|
366
|
+
2. Verify `alwaysOnTop` is true
|
|
367
|
+
3. Test with `overlayWindow.show()`
|
|
368
|
+
4. Check GPU acceleration settings
|
|
369
|
+
|
|
370
|
+
### Click-Through Not Working
|
|
371
|
+
1. Verify `setIgnoreMouseEvents(true, {forward: true})`
|
|
372
|
+
2. Check CSS `pointer-events` on elements
|
|
373
|
+
3. Test in different applications
|
|
374
|
+
4. Check for conflicting event handlers
|
|
375
|
+
|
|
376
|
+
### Chat Not Showing
|
|
377
|
+
1. Verify `chatWindow.show()` is called
|
|
378
|
+
2. Check window position (may be off-screen)
|
|
379
|
+
3. Verify not hidden behind other windows
|
|
380
|
+
4. Check `skipTaskbar` setting
|
|
381
|
+
|
|
382
|
+
### IPC Messages Not Received
|
|
383
|
+
1. Verify preload script loaded
|
|
384
|
+
2. Check `contextBridge` exposure
|
|
385
|
+
3. Enable IPC logging in DevTools
|
|
386
|
+
4. Verify correct channel names
|
|
387
|
+
|
|
388
|
+
## Best Practices
|
|
389
|
+
|
|
390
|
+
### DO
|
|
391
|
+
- Use context isolation
|
|
392
|
+
- Disable node integration in renderers
|
|
393
|
+
- Minimize renderer dependencies
|
|
394
|
+
- Implement proper cleanup on window close
|
|
395
|
+
- Use debouncing for frequent events
|
|
396
|
+
- Test on both platforms
|
|
397
|
+
|
|
398
|
+
### DON'T
|
|
399
|
+
- Enable node integration in production
|
|
400
|
+
- Load remote content without validation
|
|
401
|
+
- Create/destroy windows repeatedly
|
|
402
|
+
- Poll continuously in background
|
|
403
|
+
- Ignore security warnings
|
|
404
|
+
- Assume platform consistency
|
|
405
|
+
|
|
406
|
+
## References
|
|
407
|
+
|
|
408
|
+
- [Electron Documentation](https://electronjs.org/docs)
|
|
409
|
+
- [Electron Security Guide](https://electronjs.org/docs/tutorial/security)
|
|
410
|
+
- [IPC Communication](https://electronjs.org/docs/api/ipc-main)
|
|
411
|
+
- [BrowserWindow API](https://electronjs.org/docs/api/browser-window)
|
package/CONFIGURATION.md
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Configuration Examples
|
|
2
|
+
|
|
3
|
+
## Window Configuration
|
|
4
|
+
|
|
5
|
+
### Overlay Window Settings
|
|
6
|
+
|
|
7
|
+
You can customize the overlay window behavior in `src/main/index.js`:
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// Adjust window level for macOS
|
|
11
|
+
overlayWindow.setAlwaysOnTop(true, 'screen-saver'); // Options: 'normal', 'floating', 'torn-off-menu', 'modal-panel', 'main-menu', 'status', 'pop-up-menu', 'screen-saver'
|
|
12
|
+
|
|
13
|
+
// Adjust dot grid spacing
|
|
14
|
+
const spacing = 100; // Change to 50 for finer grid, 200 for coarser
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Chat Window Position
|
|
18
|
+
|
|
19
|
+
Modify chat window position in `src/main/index.js`:
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
// Bottom-right (default)
|
|
23
|
+
const chatWidth = 350;
|
|
24
|
+
const chatHeight = 500;
|
|
25
|
+
const margin = 20;
|
|
26
|
+
x: width - chatWidth - margin,
|
|
27
|
+
y: height - chatHeight - margin,
|
|
28
|
+
|
|
29
|
+
// Top-right
|
|
30
|
+
x: width - chatWidth - margin,
|
|
31
|
+
y: margin,
|
|
32
|
+
|
|
33
|
+
// Bottom-left
|
|
34
|
+
x: margin,
|
|
35
|
+
y: height - chatHeight - margin,
|
|
36
|
+
|
|
37
|
+
// Center
|
|
38
|
+
x: (width - chatWidth) / 2,
|
|
39
|
+
y: (height - chatHeight) / 2,
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Hotkey Configuration
|
|
43
|
+
|
|
44
|
+
Global hotkeys can be customized in `src/main/index.js`:
|
|
45
|
+
|
|
46
|
+
```javascript
|
|
47
|
+
// Toggle chat window
|
|
48
|
+
globalShortcut.register('CommandOrControl+Alt+Space', () => {
|
|
49
|
+
toggleChat();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Toggle overlay
|
|
53
|
+
globalShortcut.register('CommandOrControl+Shift+O', () => {
|
|
54
|
+
toggleOverlay();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Alternative hotkeys:
|
|
58
|
+
// 'CommandOrControl+Shift+A' - Command/Ctrl + Shift + A
|
|
59
|
+
// 'Alt+Space' - Alt + Space
|
|
60
|
+
// 'F12' - F12 key
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## IPC Message Schema
|
|
64
|
+
|
|
65
|
+
### Overlay → Main → Chat
|
|
66
|
+
|
|
67
|
+
**Dot Selection:**
|
|
68
|
+
```javascript
|
|
69
|
+
{
|
|
70
|
+
id: 'dot-100-200', // Unique dot identifier
|
|
71
|
+
x: 100, // Screen X coordinate
|
|
72
|
+
y: 200, // Screen Y coordinate
|
|
73
|
+
label: 'A2', // Human-readable label
|
|
74
|
+
timestamp: 1641234567890 // Unix timestamp
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Chat → Main → Overlay
|
|
79
|
+
|
|
80
|
+
**Mode Change:**
|
|
81
|
+
```javascript
|
|
82
|
+
'passive' // Click-through mode
|
|
83
|
+
'selection' // Interactive mode
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Chat Message:**
|
|
87
|
+
```javascript
|
|
88
|
+
{
|
|
89
|
+
text: 'Click the save button',
|
|
90
|
+
timestamp: 1641234567890
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Main → Chat
|
|
95
|
+
|
|
96
|
+
**Agent Response:**
|
|
97
|
+
```javascript
|
|
98
|
+
{
|
|
99
|
+
text: 'I found 3 buttons that might be "save"',
|
|
100
|
+
timestamp: 1641234567890
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Styling Customization
|
|
105
|
+
|
|
106
|
+
### Overlay Dots
|
|
107
|
+
|
|
108
|
+
Edit `src/renderer/overlay/index.html`:
|
|
109
|
+
|
|
110
|
+
```css
|
|
111
|
+
.dot {
|
|
112
|
+
width: 8px; /* Dot size */
|
|
113
|
+
height: 8px;
|
|
114
|
+
background: rgba(0, 122, 255, 0.7); /* Dot color */
|
|
115
|
+
border: 1px solid rgba(255, 255, 255, 0.8); /* Border */
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.dot:hover {
|
|
119
|
+
width: 12px; /* Hover size */
|
|
120
|
+
height: 12px;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Chat Window Theme
|
|
125
|
+
|
|
126
|
+
Edit `src/renderer/chat/index.html`:
|
|
127
|
+
|
|
128
|
+
```css
|
|
129
|
+
body {
|
|
130
|
+
background: #1e1e1e; /* Dark theme background */
|
|
131
|
+
color: #d4d4d4; /* Text color */
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Light theme alternative:
|
|
135
|
+
body {
|
|
136
|
+
background: #ffffff;
|
|
137
|
+
color: #1e1e1e;
|
|
138
|
+
}
|
|
139
|
+
*/
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Performance Tuning
|
|
143
|
+
|
|
144
|
+
### Memory Optimization
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
// Adjust dot density based on screen size
|
|
148
|
+
const screenArea = window.innerWidth * window.innerHeight;
|
|
149
|
+
const spacing = screenArea > 3000000 ? 150 : 100; // Larger spacing for large screens
|
|
150
|
+
|
|
151
|
+
// Lazy rendering - only render visible dots
|
|
152
|
+
function generateVisibleDots(viewportX, viewportY, viewportW, viewportH) {
|
|
153
|
+
// Implementation for viewport-based rendering
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Disable DevTools in Production
|
|
158
|
+
|
|
159
|
+
In `src/main/index.js`:
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
// Add to BrowserWindow options
|
|
163
|
+
webPreferences: {
|
|
164
|
+
devTools: process.env.NODE_ENV !== 'production'
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Agent Integration
|
|
169
|
+
|
|
170
|
+
### Connecting to External Agent
|
|
171
|
+
|
|
172
|
+
Replace the echo stub in `src/main/index.js`:
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
const axios = require('axios'); // npm install axios
|
|
176
|
+
|
|
177
|
+
ipcMain.on('chat-message', async (event, message) => {
|
|
178
|
+
try {
|
|
179
|
+
// Call external agent API
|
|
180
|
+
const response = await axios.post('http://localhost:8080/agent', {
|
|
181
|
+
message,
|
|
182
|
+
context: {
|
|
183
|
+
mode: overlayMode,
|
|
184
|
+
timestamp: Date.now()
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// Forward response to chat
|
|
189
|
+
if (chatWindow) {
|
|
190
|
+
chatWindow.webContents.send('agent-response', {
|
|
191
|
+
text: response.data.text,
|
|
192
|
+
timestamp: Date.now()
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.error('Agent error:', error);
|
|
197
|
+
chatWindow.webContents.send('agent-response', {
|
|
198
|
+
text: 'Agent unavailable',
|
|
199
|
+
timestamp: Date.now()
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Using Worker Process
|
|
206
|
+
|
|
207
|
+
```javascript
|
|
208
|
+
const { fork } = require('child_process');
|
|
209
|
+
|
|
210
|
+
// In main process
|
|
211
|
+
const agentWorker = fork(path.join(__dirname, 'agent-worker.js'));
|
|
212
|
+
|
|
213
|
+
agentWorker.on('message', (response) => {
|
|
214
|
+
if (chatWindow) {
|
|
215
|
+
chatWindow.webContents.send('agent-response', response);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
ipcMain.on('chat-message', (event, message) => {
|
|
220
|
+
agentWorker.send({ type: 'message', data: message });
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Platform-Specific Tweaks
|
|
225
|
+
|
|
226
|
+
### macOS
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
// Enable better fullscreen behavior
|
|
230
|
+
if (process.platform === 'darwin') {
|
|
231
|
+
app.dock.hide(); // Hide from dock
|
|
232
|
+
|
|
233
|
+
// Enable accessibility permissions check
|
|
234
|
+
const { systemPreferences } = require('electron');
|
|
235
|
+
if (!systemPreferences.isTrustedAccessibilityClient(false)) {
|
|
236
|
+
console.log('Requesting accessibility permissions');
|
|
237
|
+
systemPreferences.isTrustedAccessibilityClient(true);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Windows
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
// Enable Windows-specific features
|
|
246
|
+
if (process.platform === 'win32') {
|
|
247
|
+
// Set app user model ID for notifications
|
|
248
|
+
app.setAppUserModelId('com.github.copilot.agent');
|
|
249
|
+
|
|
250
|
+
// Configure window to stay above taskbar
|
|
251
|
+
overlayWindow.setAlwaysOnTop(true, 'screen-saver', 1);
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Security Best Practices
|
|
256
|
+
|
|
257
|
+
### Content Security Policy
|
|
258
|
+
|
|
259
|
+
The application already uses CSP headers. To customize:
|
|
260
|
+
|
|
261
|
+
```html
|
|
262
|
+
<meta http-equiv="Content-Security-Policy"
|
|
263
|
+
content="default-src 'self';
|
|
264
|
+
script-src 'self';
|
|
265
|
+
style-src 'self' 'unsafe-inline';
|
|
266
|
+
img-src 'self' data:;">
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Secure IPC
|
|
270
|
+
|
|
271
|
+
All IPC communication uses context isolation and preload scripts. Never:
|
|
272
|
+
- Enable `nodeIntegration: true` in production
|
|
273
|
+
- Disable `contextIsolation`
|
|
274
|
+
- Load remote content without validation
|
|
275
|
+
|
|
276
|
+
## Development vs Production
|
|
277
|
+
|
|
278
|
+
### Development Mode
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Enable DevTools and verbose logging
|
|
282
|
+
NODE_ENV=development npm start
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Production Build
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Disable DevTools, enable optimizations
|
|
289
|
+
NODE_ENV=production npm start
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Add to package.json:
|
|
293
|
+
|
|
294
|
+
```json
|
|
295
|
+
{
|
|
296
|
+
"scripts": {
|
|
297
|
+
"start:dev": "NODE_ENV=development electron .",
|
|
298
|
+
"start:prod": "NODE_ENV=production electron .",
|
|
299
|
+
"package": "electron-builder"
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|