@hanzo/browser-extension 1.7.2 → 1.7.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/browser-extension",
3
- "version": "1.7.2",
3
+ "version": "1.7.5",
4
4
  "description": "Hanzo AI Browser Extension",
5
5
  "main": "dist/background.js",
6
6
  "scripts": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Hanzo AI",
4
- "version": "1.7.2",
4
+ "version": "1.7.5",
5
5
  "description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
6
6
  "permissions": [
7
7
  "activeTab",
package/src/manifest.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "Hanzo AI",
4
- "version": "1.7.2",
4
+ "version": "1.7.5",
5
5
  "description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
6
6
  "permissions": [
7
7
  "activeTab",
package/src/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzo/browser-extension",
3
- "version": "1.7.2",
3
+ "version": "1.7.5",
4
4
  "description": "Browser extension for click-to-code navigation with MCP integration",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -1,93 +0,0 @@
1
- import React from 'react';
2
- import { createRoot } from 'react-dom/client';
3
- import { flushSync } from 'react-dom';
4
- import {
5
- Button,
6
- Card,
7
- CardContent,
8
- CardDescription,
9
- CardHeader,
10
- CardTitle,
11
- Textarea,
12
- } from '@hanzo/ui/primitives-common';
13
-
14
- function LoginPrompt() {
15
- return (
16
- <Card className="chat-modern-login-card">
17
- <CardHeader>
18
- <CardTitle>Chat with Zen AI models</CardTitle>
19
- <CardDescription>Models enabled in Hanzo Cloud are loaded automatically.</CardDescription>
20
- </CardHeader>
21
- <CardContent>
22
- <Button id="auth-btn" className="chat-modern-auth-btn" type="button">
23
- Sign in
24
- </Button>
25
- <p className="auth-note">
26
- Browser tools work without sign-in.{' '}
27
- <a href="https://docs.hanzo.ai" target="_blank" rel="noreferrer">
28
- Learn more
29
- </a>
30
- </p>
31
- </CardContent>
32
- </Card>
33
- );
34
- }
35
-
36
- function ChatComposer() {
37
- return (
38
- <div className="chat-modern-composer">
39
- <div className="model-selector">
40
- <select id="model-select">
41
- <option value="claude-sonnet-4-20250514">Claude Sonnet 4</option>
42
- <option value="claude-opus-4-20250514">Claude Opus 4</option>
43
- <option value="gpt-4o">GPT-4o</option>
44
- <option value="zen-coder-flash">Zen Coder Flash</option>
45
- <option value="zen-max">Zen Max</option>
46
- </select>
47
- </div>
48
-
49
- <div className="chat-flags">
50
- <label className="flag-toggle">
51
- <input type="checkbox" id="rag-enabled" defaultChecked />
52
- <span>RAG</span>
53
- </label>
54
- <label className="flag-toggle">
55
- <input type="checkbox" id="tab-context-enabled" defaultChecked />
56
- <span>Tab Context</span>
57
- </label>
58
- <span id="rag-status" className="rag-status">
59
- Ready
60
- </span>
61
- </div>
62
-
63
- <div className="input-row">
64
- <Textarea id="chat-input" className="chat-modern-input" placeholder="Ask anything..." rows={1} />
65
- <Button id="send-btn" className="send-btn chat-modern-send" title="Send" type="button">
66
- <svg viewBox="0 0 20 20" fill="none" stroke="currentColor" aria-hidden="true">
67
- <path d="M4 10l12-6-6 12-2-6-4-2z" strokeWidth="1.5" fill="currentColor" />
68
- </svg>
69
- </Button>
70
- </div>
71
- </div>
72
- );
73
- }
74
-
75
- export function mountModernChatWidget() {
76
- const loginTarget = document.getElementById('chat-login-prompt');
77
- if (loginTarget) {
78
- loginTarget.innerHTML = '';
79
- const loginRoot = createRoot(loginTarget);
80
- flushSync(() => {
81
- loginRoot.render(<LoginPrompt />);
82
- });
83
- }
84
-
85
- const composerTarget = document.getElementById('chat-composer');
86
- if (composerTarget) {
87
- composerTarget.innerHTML = '';
88
- const composerRoot = createRoot(composerTarget);
89
- flushSync(() => {
90
- composerRoot.render(<ChatComposer />);
91
- });
92
- }
93
- }
package/src/popup.js DELETED
@@ -1,192 +0,0 @@
1
- // Hanzo AI — Popup Script
2
- // Uses background message passing for auth (not direct storage access).
3
-
4
- document.addEventListener('DOMContentLoaded', () => {
5
- const loginSection = document.getElementById('login-section');
6
- const mainSection = document.getElementById('main-section');
7
- const settingsSection = document.getElementById('settings-section');
8
-
9
- // Auth
10
- const loginBtn = document.getElementById('login-btn');
11
- const logoutBtn = document.getElementById('logout-btn');
12
-
13
- // Open panel
14
- const openPanel = document.getElementById('open-panel');
15
-
16
- // Status dots
17
- const zapStatus = document.getElementById('zap-status');
18
- const zapDetail = document.getElementById('zap-detail');
19
- const mcpStatus = document.getElementById('mcp-status');
20
- const mcpPort = document.getElementById('mcp-port');
21
- const cdpStatus = document.getElementById('cdp-status');
22
- const cdpDetail = document.getElementById('cdp-detail');
23
- const gpuStatus = document.getElementById('gpu-status');
24
- const gpuDetail = document.getElementById('gpu-detail');
25
-
26
- // Settings
27
- const openSettings = document.getElementById('open-settings');
28
- const backBtn = document.getElementById('back-btn');
29
- const saveSettings = document.getElementById('save-settings');
30
- const testConnection = document.getElementById('test-connection');
31
-
32
- // --- Auth via background ---
33
- function checkAuth() {
34
- // Always show main section and status (tools work without login)
35
- mainSection.classList.remove('hidden');
36
- refreshStatus();
37
-
38
- chrome.runtime.sendMessage({ action: 'auth.status' }, (response) => {
39
- if (chrome.runtime.lastError) return;
40
- if (response?.success && response.authenticated) {
41
- loginSection.classList.add('hidden');
42
- if (response.user) {
43
- const avatar = document.getElementById('user-avatar');
44
- const name = document.getElementById('user-name');
45
- const email = document.getElementById('user-email');
46
- avatar.src = response.user.picture || response.user.avatar || 'icon48.png';
47
- name.textContent = response.user.name || response.user.displayName || 'Hanzo User';
48
- email.textContent = response.user.email || '';
49
- }
50
- } else {
51
- loginSection.classList.remove('hidden');
52
- }
53
- });
54
- }
55
-
56
- loginBtn?.addEventListener('click', () => {
57
- loginBtn.disabled = true;
58
- loginBtn.textContent = 'Signing in...';
59
- chrome.runtime.sendMessage({ action: 'auth.login' }, (response) => {
60
- loginBtn.disabled = false;
61
- loginBtn.innerHTML = '<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4M10 17l5-5-5-5M15 12H3"/></svg> Sign in with Hanzo';
62
- if (response?.success) {
63
- checkAuth();
64
- }
65
- });
66
- });
67
-
68
- logoutBtn?.addEventListener('click', () => {
69
- chrome.runtime.sendMessage({ action: 'auth.logout' }, () => {
70
- mainSection.classList.add('hidden');
71
- loginSection.classList.remove('hidden');
72
- });
73
- });
74
-
75
- // --- Open side panel ---
76
- openPanel?.addEventListener('click', () => {
77
- if (chrome.sidePanel) {
78
- chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
79
- if (tabs[0]?.id) {
80
- chrome.sidePanel.open({ tabId: tabs[0].id });
81
- }
82
- });
83
- } else {
84
- // Firefox: sidebar_action is automatic
85
- window.close();
86
- }
87
- });
88
-
89
- // --- Status ---
90
- function refreshStatus() {
91
- // ZAP status
92
- chrome.runtime.sendMessage({ action: 'zap.status' }, (response) => {
93
- if (chrome.runtime.lastError) return;
94
- if (response?.success) {
95
- const zap = response.zap;
96
- if (zap.connected) {
97
- zapStatus.classList.add('connected');
98
- zapStatus.classList.remove('disconnected');
99
- const mcpCount = zap.mcps?.length || 0;
100
- const toolCount = zap.mcps?.reduce((sum, m) => sum + (m.tools?.length || 0), 0) || 0;
101
- zapDetail.textContent = `${mcpCount} MCP(s), ${toolCount} tools`;
102
- } else {
103
- zapStatus.classList.remove('connected');
104
- zapStatus.classList.add('disconnected');
105
- zapDetail.textContent = 'Not connected';
106
- }
107
- }
108
- });
109
-
110
- // GPU status
111
- chrome.runtime.sendMessage({ action: 'runLocalAI', prompt: '' }, (response) => {
112
- if (chrome.runtime.lastError) return;
113
- gpuStatus.classList.add(response?.success ? 'connected' : 'disconnected');
114
- gpuStatus.classList.remove(response?.success ? 'disconnected' : 'connected');
115
- gpuDetail.textContent = response?.success ? 'Available' : 'Not available';
116
- });
117
-
118
- // MCP/CDP — set as active for now (checked via ZAP)
119
- mcpStatus.classList.add('connected');
120
- mcpPort.textContent = 'Fallback';
121
- cdpStatus.classList.add('connected');
122
- cdpDetail.textContent = 'Active';
123
- }
124
-
125
- // --- Settings ---
126
- openSettings?.addEventListener('click', () => {
127
- mainSection.classList.add('hidden');
128
- settingsSection.classList.remove('hidden');
129
- loadSettings();
130
- });
131
-
132
- backBtn?.addEventListener('click', () => {
133
- settingsSection.classList.add('hidden');
134
- mainSection.classList.remove('hidden');
135
- });
136
-
137
- function loadSettings() {
138
- chrome.storage.local.get(['mcpPort', 'cdpPort', 'zapPorts'], (result) => {
139
- const mcpPortInput = document.getElementById('mcp-port-setting');
140
- const cdpPortInput = document.getElementById('cdp-port-setting');
141
- const zapPortsInput = document.getElementById('zap-ports-setting');
142
-
143
- if (mcpPortInput) mcpPortInput.value = result.mcpPort || 3001;
144
- if (cdpPortInput) cdpPortInput.value = result.cdpPort || 9223;
145
- if (zapPortsInput) zapPortsInput.value = (result.zapPorts || [9999, 9998, 9997, 9996, 9995]).join(',');
146
- });
147
- }
148
-
149
- saveSettings?.addEventListener('click', () => {
150
- const mcpPortVal = parseInt(document.getElementById('mcp-port-setting')?.value) || 3001;
151
- const cdpPortVal = parseInt(document.getElementById('cdp-port-setting')?.value) || 9223;
152
- const zapPortsVal = (document.getElementById('zap-ports-setting')?.value || '')
153
- .split(',').map(p => parseInt(p.trim())).filter(p => p > 0 && p < 65536);
154
-
155
- chrome.storage.local.set({
156
- mcpPort: mcpPortVal,
157
- cdpPort: cdpPortVal,
158
- zapPorts: zapPortsVal.length ? zapPortsVal : [9999, 9998, 9997, 9996, 9995],
159
- }, () => {
160
- saveSettings.textContent = 'Saved!';
161
- setTimeout(() => { saveSettings.textContent = 'Save Settings'; }, 1500);
162
- });
163
- });
164
-
165
- // --- Test Connection ---
166
- testConnection?.addEventListener('click', () => {
167
- testConnection.textContent = 'Testing...';
168
- testConnection.disabled = true;
169
-
170
- chrome.runtime.sendMessage({ action: 'zap.discover' }, () => {
171
- refreshStatus();
172
- testConnection.textContent = 'Test Connection';
173
- testConnection.disabled = false;
174
- });
175
- });
176
-
177
- // Feature toggles
178
- ['source-maps', 'webgpu-ai', 'browser-control', 'tab-filesystem'].forEach(id => {
179
- const checkbox = document.getElementById(id);
180
- if (checkbox) {
181
- chrome.storage.local.get([id], (result) => {
182
- checkbox.checked = result[id] !== false; // default on
183
- });
184
- checkbox.addEventListener('change', () => {
185
- chrome.storage.local.set({ [id]: checkbox.checked });
186
- });
187
- }
188
- });
189
-
190
- // Init
191
- checkAuth();
192
- });