@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 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
+ });