@hanzo/browser-extension 1.7.6 → 1.9.33
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/LICENSE +9 -18
- package/dist/browser-extension/content-script.js +1642 -123
- package/images/icon128.png +0 -0
- package/images/icon16.png +0 -0
- package/images/icon48.png +0 -0
- package/manifest.json +7 -2
- package/package.json +28 -10
- package/src/answer/AnswerEngine.tsx +553 -0
- package/src/chat-widget.tsx +96 -0
- package/src/gui-primitives.tsx +116 -0
- package/src/icon128.png +0 -0
- package/src/icon16.png +0 -0
- package/src/icon32.png +0 -0
- package/src/icon48.png +0 -0
- package/src/manifest-firefox.json +32 -13
- package/src/manifest.json +35 -11
- package/src/newtab.css +277 -0
- package/src/newtab.html +13 -0
- package/src/package.json +1 -1
- package/src/popup.css +352 -110
- package/src/popup.html +186 -47
- package/src/popup.js +196 -0
- package/src/sidebar.css +772 -156
- package/src/sidebar.html +268 -85
- package/src/sidebar.js +885 -0
- package/.github/workflows/docs.yml +0 -44
- package/.github/workflows/release.yml +0 -55
- package/README.md +0 -126
- package/dist/browser-extension/README.md +0 -43
- package/dist/browser-extension/ai-worker.js +0 -30
- package/dist/browser-extension/background-firefox.js +0 -875
- package/dist/browser-extension/background.js +0 -2732
- package/dist/browser-extension/browser-control.js +0 -683
- package/dist/browser-extension/cdp-bridge-server.js +0 -444
- package/dist/browser-extension/chrome/ai-worker.js +0 -571
- package/dist/browser-extension/chrome/background.js +0 -2732
- package/dist/browser-extension/chrome/callback.html +0 -17
- package/dist/browser-extension/chrome/content-script.js +0 -1270
- package/dist/browser-extension/chrome/icon128.png +0 -0
- package/dist/browser-extension/chrome/icon16.png +0 -0
- package/dist/browser-extension/chrome/icon32.png +0 -0
- package/dist/browser-extension/chrome/icon48.png +0 -0
- package/dist/browser-extension/chrome/manifest.json +0 -57
- package/dist/browser-extension/chrome/popup.css +0 -519
- package/dist/browser-extension/chrome/popup.html +0 -242
- package/dist/browser-extension/chrome/popup.js +0 -278
- package/dist/browser-extension/chrome/sidebar.css +0 -1176
- package/dist/browser-extension/chrome/sidebar.html +0 -280
- package/dist/browser-extension/chrome/sidebar.js +0 -779
- package/dist/browser-extension/cli.js +0 -233
- package/dist/browser-extension/firefox/ai-worker.js +0 -571
- package/dist/browser-extension/firefox/background.js +0 -875
- package/dist/browser-extension/firefox/callback.html +0 -17
- package/dist/browser-extension/firefox/content-script.js +0 -1270
- package/dist/browser-extension/firefox/icon128.png +0 -0
- package/dist/browser-extension/firefox/icon16.png +0 -0
- package/dist/browser-extension/firefox/icon32.png +0 -0
- package/dist/browser-extension/firefox/icon48.png +0 -0
- package/dist/browser-extension/firefox/manifest.json +0 -66
- package/dist/browser-extension/firefox/popup.css +0 -519
- package/dist/browser-extension/firefox/popup.html +0 -242
- package/dist/browser-extension/firefox/popup.js +0 -278
- package/dist/browser-extension/firefox/sidebar.css +0 -1176
- package/dist/browser-extension/firefox/sidebar.html +0 -280
- package/dist/browser-extension/firefox/sidebar.js +0 -779
- package/dist/browser-extension/hanzo-browser-extension-firefox-1.1.0.zip +0 -0
- package/dist/browser-extension/icon128.png +0 -0
- package/dist/browser-extension/icon16.png +0 -0
- package/dist/browser-extension/icon32.png +0 -0
- package/dist/browser-extension/icon48.png +0 -0
- package/dist/browser-extension/manifest.json +0 -57
- package/dist/browser-extension/package.json +0 -41
- package/dist/browser-extension/popup.css +0 -468
- package/dist/browser-extension/popup.html +0 -191
- package/dist/browser-extension/popup.js +0 -278
- package/dist/browser-extension/safari/Info.plist +0 -21
- package/dist/browser-extension/safari/ai-worker.js +0 -571
- package/dist/browser-extension/safari/background.js +0 -2732
- package/dist/browser-extension/safari/callback.html +0 -17
- package/dist/browser-extension/safari/content-script.js +0 -1270
- package/dist/browser-extension/safari/icon128.png +0 -0
- package/dist/browser-extension/safari/icon16.png +0 -0
- package/dist/browser-extension/safari/icon32.png +0 -0
- package/dist/browser-extension/safari/icon48.png +0 -0
- package/dist/browser-extension/safari/popup.css +0 -519
- package/dist/browser-extension/safari/popup.html +0 -242
- package/dist/browser-extension/safari/popup.js +0 -278
- package/dist/browser-extension/safari/sidebar.css +0 -1176
- package/dist/browser-extension/safari/sidebar.html +0 -280
- package/dist/browser-extension/safari/sidebar.js +0 -779
- package/dist/browser-extension/sidebar.css +0 -718
- package/dist/browser-extension/sidebar.html +0 -184
- package/dist/browser-extension/sidebar.js +0 -779
- package/dist/browser-extension/webgpu-ai.js +0 -495
- package/dist/cdp-bridge-server.js +0 -411
- package/dist/hanzo-ai-chrome-1.7.2.zip +0 -0
- package/dist/hanzo-ai-chrome-1.7.3.zip +0 -0
- package/dist/hanzo-ai-firefox-1.7.2.zip +0 -0
- package/dist/hanzo-ai-firefox-1.7.3.zip +0 -0
- package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.pbxproj +0 -1047
- package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AccentColor.colorset/Contents.json +0 -11
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -98
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@2x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/universal-icon-1024@1x.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/Contents.json +0 -6
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/Contents.json +0 -21
- package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/icon128.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Base.lproj/Main.html +0 -20
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Icon.png +0 -0
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Script.js +0 -24
- package/dist/safari/Hanzo AI/Shared (App)/Resources/Style.css +0 -61
- package/dist/safari/Hanzo AI/Shared (App)/ViewController.swift +0 -81
- package/dist/safari/Hanzo AI/Shared (Extension)/SafariWebExtensionHandler.swift +0 -42
- package/dist/safari/Hanzo AI/iOS (App)/AppDelegate.swift +0 -24
- package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/LaunchScreen.storyboard +0 -36
- package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/Main.storyboard +0 -38
- package/dist/safari/Hanzo AI/iOS (App)/Info.plist +0 -27
- package/dist/safari/Hanzo AI/iOS (App)/SceneDelegate.swift +0 -18
- package/dist/safari/Hanzo AI/iOS (Extension)/Info.plist +0 -13
- package/dist/safari/Hanzo AI/macOS (App)/AppDelegate.swift +0 -21
- package/dist/safari/Hanzo AI/macOS (App)/Base.lproj/Main.storyboard +0 -124
- package/dist/safari/Hanzo AI/macOS (App)/Info.plist +0 -8
- package/dist/safari/Hanzo AI/macOS (Extension)/Info.plist +0 -13
- package/docs/_config.yml +0 -13
- package/docs/_layouts/default.html +0 -435
- package/docs/index.md +0 -54
- package/hanzo-ai-chrome-v1.7.6.zip +0 -0
- package/hanzo-ai-firefox-v1.7.6.zip +0 -0
- package/install-extension.sh +0 -75
- package/test/claude-integration.test.ts +0 -251
- package/test/server-frameworks-edge-cases.test.ts +0 -145
- package/test/server-frameworks.test.ts +0 -395
- package/test-cdp-connection.js +0 -140
- package/tsconfig.json +0 -19
package/src/popup.html
CHANGED
|
@@ -20,48 +20,160 @@
|
|
|
20
20
|
</header>
|
|
21
21
|
|
|
22
22
|
<!-- Login Section -->
|
|
23
|
-
<div id="login-section" class="section">
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
<div id="login-section" class="section login-section">
|
|
24
|
+
<div class="login-card">
|
|
25
|
+
<svg class="login-logo" viewBox="0 0 67 67" xmlns="http://www.w3.org/2000/svg">
|
|
26
|
+
<path d="M22.21 67V44.6369H0V67H22.21Z" fill="currentColor"/>
|
|
27
|
+
<path d="M66.7038 22.3184H22.2534L0.0878906 44.6367H44.4634L66.7038 22.3184Z" fill="currentColor"/>
|
|
28
|
+
<path d="M22.21 0H0V22.3184H22.21V0Z" fill="currentColor"/>
|
|
29
|
+
<path d="M66.7198 0H44.5098V22.3184H66.7198V0Z" fill="currentColor"/>
|
|
30
|
+
<path d="M66.7198 67V44.6369H44.5098V67H66.7198Z" fill="currentColor"/>
|
|
31
|
+
</svg>
|
|
32
|
+
<h2 class="login-headline">Sign in to Hanzo AI</h2>
|
|
33
|
+
<p class="login-sub">Chat with AI, use browser tools, and build with agents.</p>
|
|
34
|
+
<button id="login-btn" class="login-signin-btn">Sign In</button>
|
|
35
|
+
<button id="signup-btn-popup" class="login-create-btn">Create account</button>
|
|
36
|
+
<p class="login-note">
|
|
37
|
+
Browser tools work without sign-in. <a href="https://docs.hanzo.ai" target="_blank">Learn more</a>
|
|
38
|
+
</p>
|
|
39
|
+
</div>
|
|
31
40
|
</div>
|
|
32
41
|
|
|
33
42
|
<!-- Main Section (shown after login) -->
|
|
34
43
|
<div id="main-section" class="section hidden">
|
|
35
|
-
<div
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
<div
|
|
39
|
-
|
|
44
|
+
<div id="user-info-section" class="hidden">
|
|
45
|
+
<div class="user-info">
|
|
46
|
+
<img id="user-avatar" class="avatar" src="" alt="">
|
|
47
|
+
<div>
|
|
48
|
+
<div id="user-name" class="user-name"></div>
|
|
49
|
+
<div id="user-email" class="user-email"></div>
|
|
50
|
+
</div>
|
|
51
|
+
<button id="logout-btn" class="btn-icon" title="Sign out">
|
|
52
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
53
|
+
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/>
|
|
54
|
+
</svg>
|
|
55
|
+
</button>
|
|
40
56
|
</div>
|
|
41
|
-
<
|
|
42
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
43
|
-
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/>
|
|
44
|
-
</svg>
|
|
45
|
-
</button>
|
|
57
|
+
<div class="divider"></div>
|
|
46
58
|
</div>
|
|
47
59
|
|
|
48
|
-
|
|
60
|
+
<!-- Embedded search: run a query through the Hanzo answer engine. -->
|
|
61
|
+
<form id="search-form" style="display:flex;gap:6px;margin-bottom:10px;">
|
|
62
|
+
<input id="search-input" type="text" placeholder="Search Hanzo AI…" autocomplete="off"
|
|
63
|
+
style="flex:1;min-width:0;padding:9px 12px;background:var(--surface-light,#171717);border:1px solid var(--border,rgba(255,255,255,0.12));border-radius:8px;color:var(--text,#fafafa);font-size:13px;font-family:inherit;outline:none;">
|
|
64
|
+
<button id="search-btn" type="submit" title="Search" aria-label="Search"
|
|
65
|
+
style="width:36px;height:36px;flex-shrink:0;display:flex;align-items:center;justify-content:center;background:var(--primary,#fafafa);border:none;border-radius:8px;color:#000;cursor:pointer;">
|
|
66
|
+
<svg viewBox="0 0 16 16" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.8">
|
|
67
|
+
<circle cx="7" cy="7" r="4.5"/><path d="M11 11l3.5 3.5" stroke-linecap="round"/>
|
|
68
|
+
</svg>
|
|
69
|
+
</button>
|
|
70
|
+
</form>
|
|
49
71
|
|
|
50
|
-
<!-- Open Chat
|
|
51
|
-
<button id="open-panel" class="btn btn-
|
|
72
|
+
<!-- Actions: single Open Chat button + on-page surface settings. -->
|
|
73
|
+
<button id="open-panel" class="btn btn-secondary" style="margin-bottom: 8px;">
|
|
52
74
|
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
53
75
|
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
|
|
54
76
|
</svg>
|
|
55
|
-
Open Chat
|
|
56
|
-
</button>
|
|
57
|
-
<button id="open-page-overlay" class="btn btn-secondary" style="margin-bottom: 16px;">
|
|
58
|
-
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
|
59
|
-
<path d="M4 4h16v12H8l-4 4V4z"/>
|
|
60
|
-
</svg>
|
|
61
|
-
Toggle On-Page Overlay
|
|
77
|
+
Open Chat
|
|
62
78
|
</button>
|
|
63
79
|
|
|
80
|
+
<!-- On-page chat config -->
|
|
81
|
+
<div class="onpage-config" style="display:flex;flex-direction:column;gap:6px;margin-bottom:12px;font-size:11px;">
|
|
82
|
+
<div class="feature-toggle" style="display:flex;justify-content:space-between;align-items:center;">
|
|
83
|
+
<label style="display:flex;align-items:center;gap:6px;cursor:pointer;">
|
|
84
|
+
<input type="checkbox" id="overlay-enabled" checked>
|
|
85
|
+
<span>On-page chat panel</span>
|
|
86
|
+
</label>
|
|
87
|
+
<span style="color:var(--text-muted,#888);font-size:10px;">overlay vs new tab</span>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<div id="overlay-side-row" class="side-picker" style="display:flex;gap:6px;align-items:center;">
|
|
91
|
+
<span style="color:var(--text-muted,#888);">Pin:</span>
|
|
92
|
+
<button id="pin-left" class="btn btn-ghost" style="flex:1;padding:4px 8px;font-size:11px;">Left</button>
|
|
93
|
+
<button id="pin-right" class="btn btn-ghost" style="flex:1;padding:4px 8px;font-size:11px;" data-active="true">Right</button>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<div id="overlay-width-row" style="display:flex;gap:6px;align-items:center;">
|
|
97
|
+
<span style="color:var(--text-muted,#888);">Width:</span>
|
|
98
|
+
<button class="btn btn-ghost width-btn" data-width="compact" style="flex:1;padding:4px 8px;font-size:11px;">Compact</button>
|
|
99
|
+
<button class="btn btn-ghost width-btn" data-width="default" style="flex:1;padding:4px 8px;font-size:11px;" data-active="true">Default</button>
|
|
100
|
+
<button class="btn btn-ghost width-btn" data-width="wide" style="flex:1;padding:4px 8px;font-size:11px;">Wide</button>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<span style="color:var(--text-muted,#888);font-size:10px;line-height:1.4;">
|
|
104
|
+
FF native sidebar: View → Sidebar → Hanzo AI.<br>
|
|
105
|
+
Disable to fall back to a standalone tab — useful on sites with strict CSP.
|
|
106
|
+
</span>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div class="divider"></div>
|
|
110
|
+
|
|
111
|
+
<!-- AI Usage (Claude + Codex, from the current browser session) -->
|
|
112
|
+
<div class="usage-header" style="display:flex;align-items:center;justify-content:space-between;">
|
|
113
|
+
<h3>AI Usage</h3>
|
|
114
|
+
<button id="usage-refresh" class="btn-icon" title="Refresh usage">
|
|
115
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
116
|
+
<path d="M23 4v6h-6M1 20v-6h6"/>
|
|
117
|
+
<path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>
|
|
118
|
+
</svg>
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
<div id="usage-list" class="usage-list" style="display:flex;flex-direction:column;gap:8px;"></div>
|
|
122
|
+
<a href="https://console.hanzo.ai/ai-accounts" target="_blank"
|
|
123
|
+
style="display:inline-block;margin-top:8px;font-size:11px;color:var(--text-muted,#888);">Manage AI accounts →</a>
|
|
124
|
+
|
|
125
|
+
<div class="divider"></div>
|
|
126
|
+
|
|
127
|
+
<!-- Tools -->
|
|
128
|
+
<h3>Tools</h3>
|
|
129
|
+
<div class="tools-grid">
|
|
130
|
+
<button id="tool-picker" class="tool-btn" title="Pick an element on the page">
|
|
131
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
132
|
+
<path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/>
|
|
133
|
+
<path d="M13 13l6 6"/>
|
|
134
|
+
</svg>
|
|
135
|
+
<span>Selector</span>
|
|
136
|
+
</button>
|
|
137
|
+
<button id="tool-screenshot" class="tool-btn" title="Capture visible page">
|
|
138
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
139
|
+
<path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
|
|
140
|
+
<circle cx="12" cy="13" r="4"/>
|
|
141
|
+
</svg>
|
|
142
|
+
<span>Screenshot</span>
|
|
143
|
+
</button>
|
|
144
|
+
<button id="tool-pageinfo" class="tool-btn" title="Copy page info to clipboard">
|
|
145
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
146
|
+
<circle cx="12" cy="12" r="10"/>
|
|
147
|
+
<path d="M12 16v-4M12 8h.01"/>
|
|
148
|
+
</svg>
|
|
149
|
+
<span>Page Info</span>
|
|
150
|
+
</button>
|
|
151
|
+
<button id="tool-accessibility" class="tool-btn" title="Run accessibility audit">
|
|
152
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
153
|
+
<circle cx="12" cy="4" r="2"/>
|
|
154
|
+
<path d="M12 6v6M8 8l4 2 4-2M8 22l2-6h4l2 6"/>
|
|
155
|
+
</svg>
|
|
156
|
+
<span>A11y Audit</span>
|
|
157
|
+
</button>
|
|
158
|
+
<button id="tool-performance" class="tool-btn" title="Run performance audit">
|
|
159
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
160
|
+
<path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/>
|
|
161
|
+
</svg>
|
|
162
|
+
<span>Perf Audit</span>
|
|
163
|
+
</button>
|
|
164
|
+
<button id="tool-console" class="tool-btn" title="Evaluate JS in page context">
|
|
165
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
166
|
+
<polyline points="4 17 10 11 4 5"/>
|
|
167
|
+
<line x1="12" y1="19" x2="20" y2="19"/>
|
|
168
|
+
</svg>
|
|
169
|
+
<span>Console</span>
|
|
170
|
+
</button>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<div class="divider"></div>
|
|
174
|
+
|
|
64
175
|
<!-- Features -->
|
|
176
|
+
<h3>Features</h3>
|
|
65
177
|
<div class="features">
|
|
66
178
|
<div class="feature-toggle">
|
|
67
179
|
<label>
|
|
@@ -112,7 +224,7 @@
|
|
|
112
224
|
|
|
113
225
|
<!-- Browser Backend -->
|
|
114
226
|
<div class="setting-group backend-picker">
|
|
115
|
-
<h3>
|
|
227
|
+
<h3>Backend</h3>
|
|
116
228
|
<div class="backend-select-wrapper">
|
|
117
229
|
<select id="browser-backend">
|
|
118
230
|
<option value="auto">Auto (default)</option>
|
|
@@ -131,22 +243,23 @@
|
|
|
131
243
|
<div class="divider"></div>
|
|
132
244
|
|
|
133
245
|
<!-- Connection Status -->
|
|
246
|
+
<h3>Status</h3>
|
|
134
247
|
<div class="status">
|
|
135
248
|
<div class="status-item">
|
|
136
249
|
<span class="status-dot" id="zap-status"></span>
|
|
137
|
-
<span>ZAP
|
|
250
|
+
<span>ZAP Bridge</span>
|
|
138
251
|
<span id="zap-detail" class="status-detail">Discovering...</span>
|
|
139
252
|
</div>
|
|
140
|
-
<div class="status-item">
|
|
141
|
-
<span class="status-dot" id="mcp-status"></span>
|
|
142
|
-
<span>MCP Server</span>
|
|
143
|
-
<span id="mcp-port" class="status-detail">Fallback</span>
|
|
144
|
-
</div>
|
|
145
253
|
<div class="status-item">
|
|
146
254
|
<span class="status-dot" id="cdp-status"></span>
|
|
147
255
|
<span>CDP Bridge</span>
|
|
148
256
|
<span id="cdp-detail" class="status-detail">Checking...</span>
|
|
149
257
|
</div>
|
|
258
|
+
<div class="status-item">
|
|
259
|
+
<span class="status-dot" id="mcp-status"></span>
|
|
260
|
+
<span>MCP Bridge</span>
|
|
261
|
+
<span id="mcp-port" class="status-detail">:9224</span>
|
|
262
|
+
</div>
|
|
150
263
|
<div class="status-item">
|
|
151
264
|
<span class="status-dot" id="gpu-status"></span>
|
|
152
265
|
<span>WebGPU</span>
|
|
@@ -158,15 +271,19 @@
|
|
|
158
271
|
|
|
159
272
|
<!-- Actions -->
|
|
160
273
|
<div class="actions">
|
|
161
|
-
<button id="test-connection" class="btn btn-
|
|
162
|
-
<button id="open-settings" class="btn btn-
|
|
274
|
+
<button id="test-connection" class="btn btn-ghost">Test Connection</button>
|
|
275
|
+
<button id="open-settings" class="btn btn-ghost">Settings</button>
|
|
163
276
|
</div>
|
|
164
277
|
|
|
165
278
|
<!-- Quick Guide -->
|
|
166
|
-
<div class="guide" style="margin-top:
|
|
167
|
-
<h3>
|
|
168
|
-
<p
|
|
169
|
-
|
|
279
|
+
<div class="guide" style="margin-top: 12px;">
|
|
280
|
+
<h3 style="text-transform: none; letter-spacing: 0; color: var(--text);">Shortcuts</h3>
|
|
281
|
+
<p>
|
|
282
|
+
<kbd id="inspect-shortcut-display">Ctrl</kbd> + <kbd>Click</kbd>
|
|
283
|
+
any element to jump to source
|
|
284
|
+
<button id="record-inspect-shortcut" class="btn-link" style="margin-left:6px;font-size:11px;">edit</button>
|
|
285
|
+
</p>
|
|
286
|
+
<p><kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>H</kbd> open Hanzo panel</p>
|
|
170
287
|
</div>
|
|
171
288
|
</div>
|
|
172
289
|
|
|
@@ -226,15 +343,37 @@
|
|
|
226
343
|
</label>
|
|
227
344
|
</div>
|
|
228
345
|
|
|
229
|
-
<
|
|
346
|
+
<div class="setting-group">
|
|
347
|
+
<h3>Keyboard</h3>
|
|
348
|
+
<label>
|
|
349
|
+
Inspect modifier
|
|
350
|
+
<div style="display:flex;gap:8px;align-items:center;margin-top:4px;">
|
|
351
|
+
<kbd id="inspect-shortcut-current" style="flex:1;font-family:monospace;padding:4px 8px;background:var(--surface-2,#222);border-radius:4px;font-size:12px;">Ctrl</kbd>
|
|
352
|
+
<button id="inspect-shortcut-record" type="button" class="btn btn-ghost" style="padding:4px 10px;">Record</button>
|
|
353
|
+
<button id="inspect-shortcut-reset" type="button" class="btn btn-ghost" style="padding:4px 10px;">Reset</button>
|
|
354
|
+
</div>
|
|
355
|
+
<small style="color:var(--text-muted,#888);font-size:11px;">
|
|
356
|
+
Hold + click any element on a page to jump to its source. Default
|
|
357
|
+
is Ctrl (or ⌘ on Mac). Click "Record" then press the chord you
|
|
358
|
+
want — modifiers alone or modifier+letter both work.
|
|
359
|
+
</small>
|
|
360
|
+
</label>
|
|
361
|
+
</div>
|
|
230
362
|
|
|
231
|
-
<
|
|
232
|
-
<a href="https://console.hanzo.ai" target="_blank">Console</a> •
|
|
233
|
-
<a href="https://billing.hanzo.ai" target="_blank">Billing</a> •
|
|
234
|
-
<a href="https://docs.hanzo.ai" target="_blank">Docs</a>
|
|
235
|
-
</p>
|
|
363
|
+
<button id="save-settings" class="btn btn-primary">Save Settings</button>
|
|
236
364
|
</div>
|
|
237
365
|
</div>
|
|
366
|
+
|
|
367
|
+
<!-- Footer: version + nav links -->
|
|
368
|
+
<div class="footer-version" style="text-align:center;font-size:10px;color:var(--text-muted,#888);margin-top:14px;letter-spacing:0.04em;">
|
|
369
|
+
Hanzo AI <span id="footer-version">…</span>
|
|
370
|
+
</div>
|
|
371
|
+
<div class="footer-links">
|
|
372
|
+
<a href="https://docs.hanzo.ai" target="_blank">Docs</a>
|
|
373
|
+
<a href="https://console.hanzo.ai" target="_blank">Console</a>
|
|
374
|
+
<a href="https://github.com/hanzoai/extension" target="_blank">GitHub</a>
|
|
375
|
+
<a href="https://hanzo.ai" target="_blank">hanzo.ai</a>
|
|
376
|
+
</div>
|
|
238
377
|
</div>
|
|
239
378
|
|
|
240
379
|
<script src="popup.js"></script>
|
package/src/popup.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
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
|
+
window.close();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
} else if (typeof browser !== 'undefined' && browser.sidebarAction) {
|
|
85
|
+
browser.sidebarAction.open();
|
|
86
|
+
window.close();
|
|
87
|
+
} else {
|
|
88
|
+
chrome.tabs.create({ url: chrome.runtime.getURL('sidebar.html') });
|
|
89
|
+
window.close();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// --- Status ---
|
|
94
|
+
function refreshStatus() {
|
|
95
|
+
// ZAP status
|
|
96
|
+
chrome.runtime.sendMessage({ action: 'zap.status' }, (response) => {
|
|
97
|
+
if (chrome.runtime.lastError) return;
|
|
98
|
+
if (response?.success) {
|
|
99
|
+
const zap = response.zap;
|
|
100
|
+
if (zap.connected) {
|
|
101
|
+
zapStatus.classList.add('connected');
|
|
102
|
+
zapStatus.classList.remove('disconnected');
|
|
103
|
+
const mcpCount = zap.mcps?.length || 0;
|
|
104
|
+
const toolCount = zap.mcps?.reduce((sum, m) => sum + (m.tools?.length || 0), 0) || 0;
|
|
105
|
+
zapDetail.textContent = `${mcpCount} MCP(s), ${toolCount} tools`;
|
|
106
|
+
} else {
|
|
107
|
+
zapStatus.classList.remove('connected');
|
|
108
|
+
zapStatus.classList.add('disconnected');
|
|
109
|
+
zapDetail.textContent = 'Not connected';
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// GPU status
|
|
115
|
+
chrome.runtime.sendMessage({ action: 'runLocalAI', prompt: '' }, (response) => {
|
|
116
|
+
if (chrome.runtime.lastError) return;
|
|
117
|
+
gpuStatus.classList.add(response?.success ? 'connected' : 'disconnected');
|
|
118
|
+
gpuStatus.classList.remove(response?.success ? 'disconnected' : 'connected');
|
|
119
|
+
gpuDetail.textContent = response?.success ? 'Available' : 'Not available';
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// MCP/CDP — set as active for now (checked via ZAP)
|
|
123
|
+
mcpStatus.classList.add('connected');
|
|
124
|
+
mcpPort.textContent = 'Fallback';
|
|
125
|
+
cdpStatus.classList.add('connected');
|
|
126
|
+
cdpDetail.textContent = 'Active';
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// --- Settings ---
|
|
130
|
+
openSettings?.addEventListener('click', () => {
|
|
131
|
+
mainSection.classList.add('hidden');
|
|
132
|
+
settingsSection.classList.remove('hidden');
|
|
133
|
+
loadSettings();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
backBtn?.addEventListener('click', () => {
|
|
137
|
+
settingsSection.classList.add('hidden');
|
|
138
|
+
mainSection.classList.remove('hidden');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
function loadSettings() {
|
|
142
|
+
chrome.storage.local.get(['mcpPort', 'cdpPort', 'zapPorts'], (result) => {
|
|
143
|
+
const mcpPortInput = document.getElementById('mcp-port-setting');
|
|
144
|
+
const cdpPortInput = document.getElementById('cdp-port-setting');
|
|
145
|
+
const zapPortsInput = document.getElementById('zap-ports-setting');
|
|
146
|
+
|
|
147
|
+
if (mcpPortInput) mcpPortInput.value = result.mcpPort || 3001;
|
|
148
|
+
if (cdpPortInput) cdpPortInput.value = result.cdpPort || 9223;
|
|
149
|
+
if (zapPortsInput) zapPortsInput.value = (result.zapPorts || [9999, 9998, 9997, 9996, 9995]).join(',');
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
saveSettings?.addEventListener('click', () => {
|
|
154
|
+
const mcpPortVal = parseInt(document.getElementById('mcp-port-setting')?.value) || 3001;
|
|
155
|
+
const cdpPortVal = parseInt(document.getElementById('cdp-port-setting')?.value) || 9223;
|
|
156
|
+
const zapPortsVal = (document.getElementById('zap-ports-setting')?.value || '')
|
|
157
|
+
.split(',').map(p => parseInt(p.trim())).filter(p => p > 0 && p < 65536);
|
|
158
|
+
|
|
159
|
+
chrome.storage.local.set({
|
|
160
|
+
mcpPort: mcpPortVal,
|
|
161
|
+
cdpPort: cdpPortVal,
|
|
162
|
+
zapPorts: zapPortsVal.length ? zapPortsVal : [9999, 9998, 9997, 9996, 9995],
|
|
163
|
+
}, () => {
|
|
164
|
+
saveSettings.textContent = 'Saved!';
|
|
165
|
+
setTimeout(() => { saveSettings.textContent = 'Save Settings'; }, 1500);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// --- Test Connection ---
|
|
170
|
+
testConnection?.addEventListener('click', () => {
|
|
171
|
+
testConnection.textContent = 'Testing...';
|
|
172
|
+
testConnection.disabled = true;
|
|
173
|
+
|
|
174
|
+
chrome.runtime.sendMessage({ action: 'zap.discover' }, () => {
|
|
175
|
+
refreshStatus();
|
|
176
|
+
testConnection.textContent = 'Test Connection';
|
|
177
|
+
testConnection.disabled = false;
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Feature toggles
|
|
182
|
+
['source-maps', 'webgpu-ai', 'browser-control', 'tab-filesystem'].forEach(id => {
|
|
183
|
+
const checkbox = document.getElementById(id);
|
|
184
|
+
if (checkbox) {
|
|
185
|
+
chrome.storage.local.get([id], (result) => {
|
|
186
|
+
checkbox.checked = result[id] !== false; // default on
|
|
187
|
+
});
|
|
188
|
+
checkbox.addEventListener('change', () => {
|
|
189
|
+
chrome.storage.local.set({ [id]: checkbox.checked });
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Init
|
|
195
|
+
checkAuth();
|
|
196
|
+
});
|