@codewithdan/zingit 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/AGENTS.md +214 -0
- package/LICENSE +21 -0
- package/README.md +301 -0
- package/bin/cli.js +90 -0
- package/client/dist/zingit-client.js +2974 -0
- package/package.json +69 -0
- package/server/dist/agents/base.d.ts +20 -0
- package/server/dist/agents/base.js +136 -0
- package/server/dist/agents/claude.d.ts +18 -0
- package/server/dist/agents/claude.js +141 -0
- package/server/dist/agents/codex.d.ts +12 -0
- package/server/dist/agents/codex.js +194 -0
- package/server/dist/agents/copilot.d.ts +12 -0
- package/server/dist/agents/copilot.js +168 -0
- package/server/dist/handlers/messageHandlers.d.ts +57 -0
- package/server/dist/handlers/messageHandlers.js +329 -0
- package/server/dist/index.d.ts +1 -0
- package/server/dist/index.js +244 -0
- package/server/dist/services/git-manager.d.ts +104 -0
- package/server/dist/services/git-manager.js +317 -0
- package/server/dist/services/index.d.ts +2 -0
- package/server/dist/services/index.js +2 -0
- package/server/dist/types.d.ts +74 -0
- package/server/dist/types.js +2 -0
- package/server/dist/utils/agent-detection.d.ts +17 -0
- package/server/dist/utils/agent-detection.js +91 -0
- package/server/dist/validation/payload.d.ts +12 -0
- package/server/dist/validation/payload.js +64 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# ZingIt - AI Agent Guide
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
ZingIt is a browser-based annotation tool that allows users to click on webpage elements and add notes/instructions. These annotations are then sent to an AI agent (Claude Code or GitHub Copilot) which can automatically implement the requested changes.
|
|
6
|
+
|
|
7
|
+
**Use case**: Point-and-click UI feedback that gets automatically implemented by AI.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
13
|
+
│ Browser │
|
|
14
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
15
|
+
│ │ ZingIt Client │ │
|
|
16
|
+
│ │ (Lit Web Components injected via bookmarklet) │ │
|
|
17
|
+
│ └──────────────────────┬──────────────────────────────┘ │
|
|
18
|
+
└─────────────────────────┼───────────────────────────────────┘
|
|
19
|
+
│ WebSocket
|
|
20
|
+
▼
|
|
21
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
22
|
+
│ ZingIt Server │
|
|
23
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
24
|
+
│ │ WebSocket │───▶│ Agent │───▶│ Claude Code │ │
|
|
25
|
+
│ │ Handler │ │ Registry │ │ or Copilot │ │
|
|
26
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
27
|
+
└─────────────────────────────────────────────────────────────┘
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Directory Structure
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
zingit/
|
|
34
|
+
├── client/ # Browser-side UI (Lit + Vite)
|
|
35
|
+
│ ├── src/
|
|
36
|
+
│ │ ├── components/ # Lit Web Components
|
|
37
|
+
│ │ │ ├── zing-ui.ts # Main orchestrator component
|
|
38
|
+
│ │ │ ├── toolbar.ts # Action buttons and status
|
|
39
|
+
│ │ │ ├── highlight.ts # Element hover highlight
|
|
40
|
+
│ │ │ ├── markers.ts # Numbered annotation badges
|
|
41
|
+
│ │ │ ├── modal.ts # Annotation input dialog
|
|
42
|
+
│ │ │ ├── settings.ts # Configuration panel
|
|
43
|
+
│ │ │ ├── response.ts # Agent response display
|
|
44
|
+
│ │ │ ├── toast.ts # Notification toasts
|
|
45
|
+
│ │ │ └── help.ts # Keyboard shortcuts overlay
|
|
46
|
+
│ │ ├── services/
|
|
47
|
+
│ │ │ ├── selector.ts # CSS selector generation
|
|
48
|
+
│ │ │ ├── storage.ts # localStorage persistence
|
|
49
|
+
│ │ │ └── websocket.ts # WebSocket client with reconnection
|
|
50
|
+
│ │ ├── utils/
|
|
51
|
+
│ │ │ ├── geometry.ts # Viewport/rect calculations
|
|
52
|
+
│ │ │ └── markdown.ts # Export formatting
|
|
53
|
+
│ │ ├── types/index.ts # TypeScript interfaces
|
|
54
|
+
│ │ └── index.ts # Entry point
|
|
55
|
+
│ ├── index.html # Dev page
|
|
56
|
+
│ ├── products.html # Test page
|
|
57
|
+
│ ├── about.html # Test page
|
|
58
|
+
│ ├── contact.html # Test page
|
|
59
|
+
│ ├── styles.css # Shared styles for test pages
|
|
60
|
+
│ └── vite.config.ts # Build config (IIFE for bookmarklet)
|
|
61
|
+
│
|
|
62
|
+
├── server/ # Node.js WebSocket server
|
|
63
|
+
│ └── src/
|
|
64
|
+
│ ├── agents/
|
|
65
|
+
│ │ ├── base.ts # Abstract base agent class
|
|
66
|
+
│ │ ├── claude.ts # Claude Code CLI integration
|
|
67
|
+
│ │ └── copilot.ts # GitHub Copilot SDK integration
|
|
68
|
+
│ ├── types.ts # Server-side TypeScript interfaces
|
|
69
|
+
│ └── index.ts # WebSocket server entry point
|
|
70
|
+
│
|
|
71
|
+
└── AGENTS.md # This file
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Tech Stack
|
|
75
|
+
|
|
76
|
+
### Client
|
|
77
|
+
- **Lit 3.x** - Web Components framework
|
|
78
|
+
- **TypeScript** - Strict mode enabled
|
|
79
|
+
- **Vite** - Dev server and build tool
|
|
80
|
+
- **Shadow DOM** - Style isolation (critical for bookmarklet injection)
|
|
81
|
+
|
|
82
|
+
### Server
|
|
83
|
+
- **Node.js** - Runtime
|
|
84
|
+
- **ws** - WebSocket library
|
|
85
|
+
- **tsx** - TypeScript execution
|
|
86
|
+
- **@anthropic-ai/claude-agent-sdk** - Claude Code integration
|
|
87
|
+
- **@github/copilot-sdk** - GitHub Copilot integration
|
|
88
|
+
|
|
89
|
+
## Key Concepts
|
|
90
|
+
|
|
91
|
+
### Annotations
|
|
92
|
+
An annotation captures:
|
|
93
|
+
- `selector` - CSS selector to locate the element
|
|
94
|
+
- `identifier` - Human-readable element description (e.g., "button.primary")
|
|
95
|
+
- `html` - Outer HTML of the element
|
|
96
|
+
- `notes` - User's instructions for changes
|
|
97
|
+
- `selectedText` - Any text the user had selected
|
|
98
|
+
- `parentContext` - Parent element path for context
|
|
99
|
+
- `textContent` - Plain text content
|
|
100
|
+
|
|
101
|
+
### WebSocket Messages
|
|
102
|
+
- **Client → Server**: `batch` (send annotations), `message` (follow-up), `reset` (clear session)
|
|
103
|
+
- **Server → Client**: `connected`, `processing`, `delta` (streaming), `tool_start`/`tool_end`, `idle`, `error`
|
|
104
|
+
|
|
105
|
+
### Agent System
|
|
106
|
+
The server uses a pluggable agent architecture:
|
|
107
|
+
- Set `AGENT=claude` or `AGENT=copilot` environment variable
|
|
108
|
+
- Agents implement `Agent` interface with `createSession()` and `formatPrompt()`
|
|
109
|
+
- Claude agent spawns `claude --print` CLI process
|
|
110
|
+
- Copilot agent uses the GitHub Copilot SDK
|
|
111
|
+
|
|
112
|
+
## Development Commands
|
|
113
|
+
|
|
114
|
+
### Client
|
|
115
|
+
```bash
|
|
116
|
+
cd client
|
|
117
|
+
npm install
|
|
118
|
+
npm run dev # Start Vite dev server (http://localhost:5200)
|
|
119
|
+
npm run build # Build for production (outputs IIFE bundle)
|
|
120
|
+
npm run typecheck # Type check without emitting
|
|
121
|
+
npm run typecheck:watch # Watch mode type checking
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Server
|
|
125
|
+
```bash
|
|
126
|
+
cd server
|
|
127
|
+
npm install
|
|
128
|
+
AGENT=claude npm run dev # Start with Claude Code agent
|
|
129
|
+
AGENT=copilot npm run dev # Start with GitHub Copilot agent
|
|
130
|
+
npm run typecheck # Type check
|
|
131
|
+
npm run typecheck:watch # Watch mode type checking
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Keyboard Shortcuts
|
|
135
|
+
|
|
136
|
+
| Key | Action |
|
|
137
|
+
|-----|--------|
|
|
138
|
+
| `P` | Toggle annotation mode on/off |
|
|
139
|
+
| `Ctrl/Cmd+Z` | Undo last annotation |
|
|
140
|
+
| `?` | Show help overlay |
|
|
141
|
+
| `` ` `` | Toggle ZingIt visibility |
|
|
142
|
+
| `Esc` | Close current panel/modal |
|
|
143
|
+
| `Ctrl/Cmd+Enter` | Save annotation (in modal) |
|
|
144
|
+
|
|
145
|
+
## State Persistence
|
|
146
|
+
|
|
147
|
+
The client persists state to `localStorage`:
|
|
148
|
+
- `zingit_annotations` - Current page annotations (URL-scoped)
|
|
149
|
+
- `zingit_settings` - User preferences (wsUrl, colors, projectDir)
|
|
150
|
+
- `zingit_active` - Annotation mode on/off (persists across pages)
|
|
151
|
+
|
|
152
|
+
## Important Implementation Details
|
|
153
|
+
|
|
154
|
+
### Shadow DOM
|
|
155
|
+
All components use Shadow DOM for style isolation. This is critical because ZingIt is injected as a bookmarklet into arbitrary pages - styles must not leak in or out.
|
|
156
|
+
|
|
157
|
+
### Viewport Coordinates
|
|
158
|
+
The highlight and marker positioning uses viewport coordinates (not page coordinates) because the main `zing-ui` component is `position: fixed`. Use `getElementViewportRect()` from `geometry.ts`.
|
|
159
|
+
|
|
160
|
+
### WebSocket Reconnection
|
|
161
|
+
The WebSocket client implements exponential backoff reconnection:
|
|
162
|
+
- Delays: 1s, 2s, 4s, 8s, 16s, 30s (capped)
|
|
163
|
+
- Max 10 attempts before showing "Reconnect" button
|
|
164
|
+
- Call `forceReconnect()` to manually retry
|
|
165
|
+
|
|
166
|
+
### Component Communication
|
|
167
|
+
Components communicate via custom events that bubble through Shadow DOM:
|
|
168
|
+
```typescript
|
|
169
|
+
this.dispatchEvent(new CustomEvent('save', {
|
|
170
|
+
bubbles: true,
|
|
171
|
+
composed: true, // Crosses shadow boundaries
|
|
172
|
+
detail: { ... }
|
|
173
|
+
}));
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Common Tasks
|
|
177
|
+
|
|
178
|
+
### Adding a New Component
|
|
179
|
+
1. Create `client/src/components/my-component.ts`
|
|
180
|
+
2. Use `@customElement('zing-my-component')` decorator
|
|
181
|
+
3. Import in `zing-ui.ts`
|
|
182
|
+
4. Add to render method with event handlers
|
|
183
|
+
|
|
184
|
+
### Adding a New Agent
|
|
185
|
+
1. Create `server/src/agents/my-agent.ts`
|
|
186
|
+
2. Extend `BaseAgent` class
|
|
187
|
+
3. Implement `createSession()` method
|
|
188
|
+
4. Register in `server/src/index.ts` agent registry
|
|
189
|
+
|
|
190
|
+
### Modifying the Toolbar
|
|
191
|
+
Edit `client/src/components/toolbar.ts`:
|
|
192
|
+
- Add new `@property()` for state
|
|
193
|
+
- Add button in `render()` method
|
|
194
|
+
- Create handler method that dispatches event
|
|
195
|
+
- Wire up event in `zing-ui.ts`
|
|
196
|
+
|
|
197
|
+
## Testing
|
|
198
|
+
|
|
199
|
+
Test pages are available at:
|
|
200
|
+
- `http://localhost:5200/` - Main demo page
|
|
201
|
+
- `http://localhost:5200/products.html` - Product cards
|
|
202
|
+
- `http://localhost:5200/about.html` - About page with stats/timeline
|
|
203
|
+
- `http://localhost:5200/contact.html` - Contact form and FAQ
|
|
204
|
+
|
|
205
|
+
## Build Output
|
|
206
|
+
|
|
207
|
+
The Vite build produces:
|
|
208
|
+
- `dist/zingit.es.js` - ES module version
|
|
209
|
+
- `dist/zingit.iife.js` - IIFE for bookmarklet injection
|
|
210
|
+
|
|
211
|
+
The IIFE can be used as a bookmarklet:
|
|
212
|
+
```javascript
|
|
213
|
+
javascript:(function(){var s=document.createElement('script');s.src='http://localhost:5200/dist/zingit.iife.js';document.body.appendChild(s);})()
|
|
214
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dan Wahlin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# ZingIt
|
|
2
|
+
|
|
3
|
+
A browser-based annotation tool that lets you highlight and comment on UI elements, then send those annotations to an AI agent for automated fixes.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Visual Annotations**: Click any element to add notes about changes you want
|
|
8
|
+
- **Smart Selectors**: Automatically generates CSS selectors for targeted elements
|
|
9
|
+
- **AI Integration**: Supports Claude Agent SDK, GitHub Copilot SDK, and OpenAI Codex SDK
|
|
10
|
+
- **Streaming Responses**: Watch the AI work in real-time
|
|
11
|
+
- **Persistent Storage**: Annotations survive page refreshes
|
|
12
|
+
- **Bookmarklet Ready**: Single-file build for easy injection
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### 1. Install Dependencies
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Server
|
|
20
|
+
cd server
|
|
21
|
+
npm install
|
|
22
|
+
|
|
23
|
+
# Client
|
|
24
|
+
cd ../client
|
|
25
|
+
npm install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. Start the Server
|
|
29
|
+
|
|
30
|
+
The server requires two environment variables:
|
|
31
|
+
- `PROJECT_DIR` - Path to the project the AI agent should work in
|
|
32
|
+
- `AGENT` - Which AI agent to use (`claude`, `copilot`, or `codex`)
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
cd server
|
|
36
|
+
|
|
37
|
+
# Using Claude Agent SDK
|
|
38
|
+
PROJECT_DIR=/path/to/your/project AGENT=claude npm run dev
|
|
39
|
+
|
|
40
|
+
# Using GitHub Copilot SDK
|
|
41
|
+
PROJECT_DIR=/path/to/your/project AGENT=copilot npm run dev
|
|
42
|
+
|
|
43
|
+
# Using OpenAI Codex SDK
|
|
44
|
+
PROJECT_DIR=/path/to/your/project AGENT=codex npm run dev
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The agent will read and edit files within the specified `PROJECT_DIR`.
|
|
48
|
+
|
|
49
|
+
You can also override this per-session in the client settings (see Configuration).
|
|
50
|
+
|
|
51
|
+
### 3. Start the Client Dev Server
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cd client
|
|
55
|
+
npm run dev
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
The browser will open automatically to `http://localhost:5200` with the demo page.
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
1. **Click any element** on the page to open the annotation modal
|
|
63
|
+
2. **Add notes** describing the issue or change you want
|
|
64
|
+
3. **Repeat** for multiple elements
|
|
65
|
+
4. Click **"Send to Agent"** to send all annotations to the AI
|
|
66
|
+
5. Watch the **response panel** for the agent's work
|
|
67
|
+
|
|
68
|
+
### Keyboard Shortcuts
|
|
69
|
+
|
|
70
|
+
- `P` - Toggle annotation mode on/off
|
|
71
|
+
- `Escape` - Close modals/panels
|
|
72
|
+
- `Cmd/Ctrl + Enter` - Save annotation in modal
|
|
73
|
+
|
|
74
|
+
## Building for Production
|
|
75
|
+
|
|
76
|
+
### Bookmarklet
|
|
77
|
+
|
|
78
|
+
Build a single-file version that can be injected via bookmarklet:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cd client
|
|
82
|
+
npm run build
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The `dist/zingit.iife.js` file contains everything needed. Create a bookmarklet:
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
javascript:(function(){var s=document.createElement('script');s.src='http://localhost:5200/zingit.iife.js';document.body.appendChild(s);})()
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### ES Module
|
|
92
|
+
|
|
93
|
+
For integration into existing projects:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cd client
|
|
97
|
+
npm run build
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Use `dist/zingit.es.js` as an ES module.
|
|
101
|
+
|
|
102
|
+
## Configuration
|
|
103
|
+
|
|
104
|
+
Click the **gear icon** in the toolbar to open settings:
|
|
105
|
+
|
|
106
|
+
| Setting | Default | Description |
|
|
107
|
+
|---------|---------|-------------|
|
|
108
|
+
| WebSocket URL | `ws://localhost:8765` | Server connection URL |
|
|
109
|
+
| Project Directory | *(empty)* | Override server's default project directory. Leave empty to use server default (shown as placeholder) |
|
|
110
|
+
| Highlight Color | `#fbbf24` | Color of element highlight on hover |
|
|
111
|
+
| Marker Color | `#3b82f6` | Color of numbered annotation markers |
|
|
112
|
+
| Auto-connect | `true` | Connect to server on startup |
|
|
113
|
+
|
|
114
|
+
Settings are saved to localStorage.
|
|
115
|
+
|
|
116
|
+
**Project Directory Priority:**
|
|
117
|
+
1. Client setting (if specified) - highest priority
|
|
118
|
+
2. Server's `PROJECT_DIR` environment variable (required)
|
|
119
|
+
|
|
120
|
+
## Architecture
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
zingit/
|
|
124
|
+
├── client/ # Browser-side Lit components
|
|
125
|
+
│ ├── src/
|
|
126
|
+
│ │ ├── components/ # Lit web components
|
|
127
|
+
│ │ │ ├── zing-ui.ts # Main orchestrator
|
|
128
|
+
│ │ │ ├── toolbar.ts # Status and actions
|
|
129
|
+
│ │ │ ├── highlight.ts # Hover overlay
|
|
130
|
+
│ │ │ ├── markers.ts # Numbered badges
|
|
131
|
+
│ │ │ ├── modal.ts # Annotation form
|
|
132
|
+
│ │ │ ├── settings.ts # Config panel
|
|
133
|
+
│ │ │ └── response.ts # AI response display
|
|
134
|
+
│ │ ├── services/ # WebSocket, storage, selectors
|
|
135
|
+
│ │ ├── utils/ # Geometry, markdown helpers
|
|
136
|
+
│ │ └── types/ # TypeScript interfaces
|
|
137
|
+
│ └── vite.config.ts
|
|
138
|
+
│
|
|
139
|
+
└── server/ # WebSocket server + AI agents
|
|
140
|
+
└── src/
|
|
141
|
+
├── agents/
|
|
142
|
+
│ ├── base.ts # Abstract agent interface
|
|
143
|
+
│ ├── claude.ts # Claude Agent SDK integration
|
|
144
|
+
│ ├── copilot.ts # GitHub Copilot SDK integration
|
|
145
|
+
│ └── codex.ts # OpenAI Codex SDK integration
|
|
146
|
+
├── types.ts
|
|
147
|
+
└── index.ts # WebSocket server
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Agents
|
|
151
|
+
|
|
152
|
+
### GitHub Copilot SDK
|
|
153
|
+
|
|
154
|
+
Uses the official `@github/copilot-sdk` package. Requires:
|
|
155
|
+
- GitHub Copilot CLI installed and in your PATH
|
|
156
|
+
- Active GitHub Copilot subscription
|
|
157
|
+
|
|
158
|
+
The SDK communicates with the Copilot CLI in server mode, handling session management, streaming responses, and tool execution automatically.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Install Copilot CLI first
|
|
162
|
+
gh extension install github/gh-copilot
|
|
163
|
+
|
|
164
|
+
# Then run the server
|
|
165
|
+
PROJECT_DIR=/path/to/your/project AGENT=copilot npm run dev
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Claude Agent SDK
|
|
169
|
+
|
|
170
|
+
Uses the official `@anthropic-ai/claude-agent-sdk` package. Requires:
|
|
171
|
+
- Claude Code installed: `npm install -g @anthropic-ai/claude-code`
|
|
172
|
+
- Valid Anthropic API key or Claude Max subscription
|
|
173
|
+
|
|
174
|
+
The SDK provides streaming responses with tool execution status, allowing the agent to read files, search code, and make edits.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
PROJECT_DIR=/path/to/your/project AGENT=claude npm run dev
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### OpenAI Codex SDK
|
|
181
|
+
|
|
182
|
+
Uses the official `@openai/codex-sdk` package. Requires:
|
|
183
|
+
- Codex CLI installed and logged in (run `codex` once to authenticate)
|
|
184
|
+
- Active ChatGPT Plus, Pro, Business, Edu, or Enterprise subscription
|
|
185
|
+
|
|
186
|
+
The SDK uses your cached Codex CLI credentials (`~/.codex/auth.json`) - no API key needed. Just login once via the browser flow.
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# First time: login to Codex (opens browser)
|
|
190
|
+
npx codex
|
|
191
|
+
|
|
192
|
+
# Then run the server
|
|
193
|
+
PROJECT_DIR=/path/to/your/project AGENT=codex npm run dev
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
You can optionally set `CODEX_MODEL` to override the default model (gpt-5.2-codex).
|
|
197
|
+
|
|
198
|
+
## API
|
|
199
|
+
|
|
200
|
+
### WebSocket Messages
|
|
201
|
+
|
|
202
|
+
**Client → Server:**
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// Send batch of annotations
|
|
206
|
+
{ type: 'batch', data: { pageUrl, pageTitle, annotations, projectDir? } }
|
|
207
|
+
|
|
208
|
+
// Send follow-up message
|
|
209
|
+
{ type: 'message', content: '...' }
|
|
210
|
+
|
|
211
|
+
// Reset session
|
|
212
|
+
{ type: 'reset' }
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Note: `projectDir` is optional. If omitted, the server uses its default (from `PROJECT_DIR` env var or cwd).
|
|
216
|
+
|
|
217
|
+
**Server → Client:**
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
{ type: 'connected', agent: 'claude', model: 'claude-sonnet-4-20250514', projectDir: '/path/to/project' }
|
|
221
|
+
{ type: 'processing' }
|
|
222
|
+
{ type: 'delta', content: '...' } // Streaming text
|
|
223
|
+
{ type: 'tool_start', tool: '...' } // Tool execution started
|
|
224
|
+
{ type: 'tool_end' } // Tool execution ended
|
|
225
|
+
{ type: 'idle' } // Processing complete
|
|
226
|
+
{ type: 'error', message: '...' }
|
|
227
|
+
{ type: 'reset_complete' }
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Troubleshooting
|
|
231
|
+
|
|
232
|
+
### "WebSocket not connected"
|
|
233
|
+
|
|
234
|
+
1. Ensure the server is running (`npm run dev` in `/server`)
|
|
235
|
+
2. Check the WebSocket URL in settings
|
|
236
|
+
3. Check browser console for connection errors
|
|
237
|
+
4. Click "Reconnect" if max attempts reached
|
|
238
|
+
|
|
239
|
+
### "Claude Code CLI not found"
|
|
240
|
+
|
|
241
|
+
Install Claude Code globally:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
npm install -g @anthropic-ai/claude-code
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Annotations not persisting
|
|
248
|
+
|
|
249
|
+
- Check if localStorage is available and not full
|
|
250
|
+
- Annotations are URL-specific; changing pages clears them
|
|
251
|
+
|
|
252
|
+
### Elements not highlighting
|
|
253
|
+
|
|
254
|
+
- ZingIt ignores its own elements (anything starting with `zing-`)
|
|
255
|
+
- Some elements may have pointer-events disabled
|
|
256
|
+
|
|
257
|
+
## Development
|
|
258
|
+
|
|
259
|
+
### Type Checking
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Client
|
|
263
|
+
cd client && npm run typecheck
|
|
264
|
+
|
|
265
|
+
# Server
|
|
266
|
+
cd server && npm run typecheck
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Testing
|
|
270
|
+
|
|
271
|
+
The server includes a test suite to validate agent WebSocket communication.
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
cd server
|
|
275
|
+
|
|
276
|
+
# Run a single test (requires server to be running)
|
|
277
|
+
npm run test # Simple scenario
|
|
278
|
+
npm run test -- --scenario=multi # Multiple annotations
|
|
279
|
+
npm run test -- --scenario=followup # With follow-up message
|
|
280
|
+
|
|
281
|
+
# Run all agents (starts/stops server automatically)
|
|
282
|
+
npm run test:all # Test all agents
|
|
283
|
+
npm run test:copilot # Test only Copilot
|
|
284
|
+
npm run test:claude # Test only Claude
|
|
285
|
+
npm run test:codex # Test only Codex
|
|
286
|
+
|
|
287
|
+
# Dry run to see what would be tested
|
|
288
|
+
./tests/run-all-tests.sh --dry-run
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
The test suite uses a sample project in `tests/test-project/` with a React file for agents to modify. Test scenarios send annotated UI changes and verify the agent responds correctly.
|
|
292
|
+
|
|
293
|
+
### Project Structure
|
|
294
|
+
|
|
295
|
+
The client uses Lit 3.x web components with Shadow DOM enabled for style isolation. This is critical for the bookmarklet use case where ZingIt must not conflict with the host page's styles.
|
|
296
|
+
|
|
297
|
+
The server is a simple WebSocket relay that forwards annotation data to the configured AI agent and streams responses back.
|
|
298
|
+
|
|
299
|
+
## License
|
|
300
|
+
|
|
301
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const colors = {
|
|
11
|
+
reset: '\x1b[0m',
|
|
12
|
+
bright: '\x1b[1m',
|
|
13
|
+
cyan: '\x1b[36m',
|
|
14
|
+
green: '\x1b[32m',
|
|
15
|
+
yellow: '\x1b[33m',
|
|
16
|
+
blue: '\x1b[34m'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function printBanner() {
|
|
20
|
+
console.log('');
|
|
21
|
+
console.log(`${colors.cyan}╔═══════════════════════════════════════════════════════════════╗${colors.reset}`);
|
|
22
|
+
console.log(`${colors.cyan}║ ║${colors.reset}`);
|
|
23
|
+
console.log(`${colors.cyan}║${colors.reset} ${colors.bright}⚡ ZingIt${colors.reset} - AI-Powered UI Annotation Tool ${colors.cyan}║${colors.reset}`);
|
|
24
|
+
console.log(`${colors.cyan}║ ║${colors.reset}`);
|
|
25
|
+
console.log(`${colors.cyan}╚═══════════════════════════════════════════════════════════════╝${colors.reset}`);
|
|
26
|
+
console.log('');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function printInstructions(port = 3000) {
|
|
30
|
+
console.log(`${colors.green}✓${colors.reset} Server running at ${colors.bright}http://localhost:${port}${colors.reset}`);
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log(`${colors.yellow}📝 How to use ZingIt:${colors.reset}`);
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(` ${colors.bright}1.${colors.reset} Add to your webpage:`);
|
|
35
|
+
console.log(` ${colors.cyan}<script src="https://cdn.jsdelivr.net/npm/@codewithdan/zingit@latest/dist/zingit-client.js"></script>${colors.reset}`);
|
|
36
|
+
console.log(` ${colors.cyan}<script>ZingIt.connect('ws://localhost:${port}');</script>${colors.reset}`);
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(` ${colors.bright}2.${colors.reset} Or visit the demo page:`);
|
|
39
|
+
console.log(` ${colors.blue}http://localhost:${port}${colors.reset}`);
|
|
40
|
+
console.log('');
|
|
41
|
+
console.log(` ${colors.bright}3.${colors.reset} Press ${colors.bright}Z${colors.reset} to toggle annotation mode`);
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(`${colors.yellow}💡 Tip:${colors.reset} Make sure you have an AI agent running (Claude Code, GitHub Copilot CLI, or OpenAI Codex)`);
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log(`Press ${colors.bright}Ctrl+C${colors.reset} to stop the server`);
|
|
46
|
+
console.log('');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function startServer() {
|
|
50
|
+
printBanner();
|
|
51
|
+
console.log(`${colors.cyan}🚀 Starting ZingIt server...${colors.reset}`);
|
|
52
|
+
console.log('');
|
|
53
|
+
|
|
54
|
+
// Path to the compiled server
|
|
55
|
+
const serverPath = join(__dirname, '..', 'server', 'dist', 'index.js');
|
|
56
|
+
|
|
57
|
+
// Start the server as a child process
|
|
58
|
+
const serverProcess = spawn('node', [serverPath], {
|
|
59
|
+
stdio: 'inherit',
|
|
60
|
+
env: { ...process.env, NODE_ENV: 'production' }
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
serverProcess.on('error', (err) => {
|
|
64
|
+
console.error(`${colors.red}✗ Failed to start server:${colors.reset}`, err);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Wait a moment for server to start, then print instructions
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
printInstructions();
|
|
71
|
+
}, 1000);
|
|
72
|
+
|
|
73
|
+
// Handle graceful shutdown
|
|
74
|
+
process.on('SIGINT', () => {
|
|
75
|
+
console.log('');
|
|
76
|
+
console.log(`${colors.yellow}⚡ Shutting down ZingIt server...${colors.reset}`);
|
|
77
|
+
serverProcess.kill('SIGINT');
|
|
78
|
+
process.exit(0);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
process.on('SIGTERM', () => {
|
|
82
|
+
serverProcess.kill('SIGTERM');
|
|
83
|
+
process.exit(0);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
startServer().catch((err) => {
|
|
88
|
+
console.error(`${colors.red}✗ Error:${colors.reset}`, err);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
});
|