@weavetab/mcp 2.5.0-beta.2 → 2.5.0-beta.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/AGENTS.md +1 -1
- package/ARCHITECTURE.md +6 -6
- package/LICENSE +216 -631
- package/README.md +153 -1074
- package/SECURITY.md +33 -22
- package/TROUBLESHOOTING.md +2 -2
- package/dist/cdp/bridge.js +2 -1
- package/dist/cdp/connector.d.ts +2 -0
- package/dist/cdp/connector.js +10 -6
- package/dist/cdp/helpers.d.ts +4 -0
- package/dist/cdp/helpers.js +181 -0
- package/dist/cdp/omni_broker.d.ts +1 -1
- package/dist/cdp/omni_broker.js +1 -1
- package/dist/cdp/walker.d.ts +25 -1
- package/dist/cdp/walker.js +304 -7
- package/dist/cli/plugin.d.ts +1 -0
- package/dist/cli/plugin.js +81 -18
- package/dist/cli/updater.d.ts +1 -1
- package/dist/cli/updater.js +27 -7
- package/dist/config/loader.d.ts +9 -1
- package/dist/config/loader.js +42 -3
- package/dist/desktop/discovery.d.ts +44 -0
- package/dist/desktop/discovery.js +364 -0
- package/dist/index.js +137 -21
- package/dist/intelligence/marks.d.ts +36 -0
- package/dist/intelligence/marks.js +30 -0
- package/dist/intelligence/patternCompiler.d.ts +118 -0
- package/dist/intelligence/patternCompiler.js +259 -0
- package/dist/intelligence/sessionMemory.d.ts +2 -0
- package/dist/intelligence/sessionMemory.js +18 -8
- package/dist/overlay/injector.js +2 -2
- package/dist/plugin/interface.d.ts +88 -5
- package/dist/plugin/loader.d.ts +12 -1
- package/dist/plugin/loader.js +280 -70
- package/dist/plugin/pipeline.d.ts +75 -0
- package/dist/plugin/pipeline.js +183 -0
- package/dist/plugin/registry.d.ts +2 -1
- package/dist/plugin/registry.js +24 -14
- package/dist/security/secrets.d.ts +7 -0
- package/dist/security/secrets.js +37 -0
- package/dist/sensors/actionability.js +1 -2
- package/dist/sensors/guard.js +4 -10
- package/dist/sensors/mutations.js +12 -0
- package/dist/sensors/operation_monitor.js +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +453 -178
- package/dist/state/agent.d.ts +1 -0
- package/dist/state/agent.js +3 -0
- package/dist/state/delta.d.ts +12 -4
- package/dist/state/delta.js +67 -14
- package/dist/state/session.d.ts +6 -0
- package/dist/state/session.js +27 -0
- package/dist/tools/browser_detect.d.ts +16 -3
- package/dist/tools/browser_detect.js +52 -7
- package/dist/tools/burst.d.ts +17 -8
- package/dist/tools/burst.js +236 -77
- package/dist/tools/captcha.js +1 -1
- package/dist/tools/checkpoint.d.ts +38 -0
- package/dist/tools/checkpoint.js +271 -0
- package/dist/tools/click.d.ts +1 -0
- package/dist/tools/click.js +74 -70
- package/dist/tools/design_extract.js +1 -1
- package/dist/tools/eval.js +1 -1
- package/dist/tools/fill.d.ts +20 -1
- package/dist/tools/fill.js +199 -40
- package/dist/tools/find.d.ts +16 -0
- package/dist/tools/find.js +67 -44
- package/dist/tools/github/index.d.ts +19 -4
- package/dist/tools/github/index.js +40 -4
- package/dist/tools/highlight.d.ts +6 -2
- package/dist/tools/highlight.js +158 -72
- package/dist/tools/inspect.js +1 -1
- package/dist/tools/key.js +65 -56
- package/dist/tools/navigate.d.ts +1 -1
- package/dist/tools/navigate.js +34 -39
- package/dist/tools/pdf.js +21 -13
- package/dist/tools/pointer.d.ts +18 -3
- package/dist/tools/pointer.js +89 -1
- package/dist/tools/read.d.ts +28 -8
- package/dist/tools/read.js +230 -56
- package/dist/tools/scrape.js +67 -13
- package/dist/tools/screenshot.js +21 -16
- package/dist/tools/scroll.js +6 -11
- package/dist/tools/select.js +8 -2
- package/dist/tools/snapshot.js +3 -34
- package/dist/tools/tabs.js +15 -7
- package/dist/tools/thought.d.ts +2 -0
- package/dist/tools/thought.js +13 -14
- package/dist/tools/type.d.ts +2 -0
- package/dist/tools/type.js +107 -58
- package/dist/tools/type_secret.js +42 -76
- package/dist/tools/upload.js +1 -1
- package/dist/tools/video_compiler.d.ts +1 -1
- package/dist/tools/video_compiler.js +11 -12
- package/dist/version.d.ts +5 -0
- package/dist/version.js +5 -0
- package/docs/DOCUMENTATION.md +37 -41
- package/docs/PLUGINS.md +121 -0
- package/docs/TOOLS.md +54 -0
- package/docs/architecture/blind-injection.md +83 -20
- package/docs/architecture/overview.md +49 -49
- package/docs/architecture/security.md +8 -7
- package/docs/architecture/transport.md +2 -2
- package/docs/cli/cli-commands.md +7 -1
- package/docs/cli/cli-flags.md +15 -7
- package/docs/cli/cli-scripting.md +6 -3
- package/docs/configuration/config-locations.md +3 -4
- package/docs/configuration/env-variables.md +4 -4
- package/docs/configuration/folders.md +55 -54
- package/docs/desktop-automation/electron-apps.md +214 -162
- package/docs/get-started/introduction.md +60 -60
- package/docs/get-started/setup-wizard.md +7 -6
- package/docs/intelligence/site-profiles.md +151 -0
- package/docs/tools/tools.md +631 -293
- package/docs/troubleshooting/trouble-browser.md +1 -1
- package/docs/troubleshooting/trouble-loop.md +31 -31
- package/ext-dist/background.js +10 -62
- package/ext-dist/content.js +333 -920
- package/ext-dist/hud/hud.js +9 -9
- package/ext-dist/manifest.json +2 -6
- package/ext-dist/styles.css +6 -1
- package/icon.png +0 -0
- package/mcp.json +87 -71
- package/package.json +118 -119
- package/server.json +5 -5
- package/ext-dist/sidepanel/sidepanel.js +0 -25
- package/ext-dist/sidepanel.html +0 -547
package/ext-dist/content.js
CHANGED
|
@@ -226,19 +226,18 @@ function __wt_safeAppendToBody(el) {
|
|
|
226
226
|
if (msg.type === 'TOOL_CALL_EVENT' && iframe && iframe.contentWindow) {
|
|
227
227
|
iframe.contentWindow.postMessage({ type: 'TOOL_CALL_EVENT', payload: msg.payload }, '*');
|
|
228
228
|
}
|
|
229
|
-
//
|
|
230
|
-
if (msg.type === 'WT_SIDEPANEL_STATE' && iframe && iframe.contentWindow) {
|
|
231
|
-
iframe.contentWindow.postMessage({ type: 'WT_SIDEPANEL_STATE', open: msg.open }, '*');
|
|
232
|
-
}
|
|
233
|
-
// Background tells us to suppress the thought pill for this specific event
|
|
234
|
-
if (msg.type === 'WT_SUPPRESS_THOUGHT_HUD' && iframe && iframe.contentWindow) {
|
|
235
|
-
iframe.contentWindow.postMessage({ type: 'WT_SUPPRESS_THOUGHT_HUD' }, '*');
|
|
236
|
-
}
|
|
237
|
-
// Scripted pill toggle from sidepanel settings — relay to HUD iframe
|
|
229
|
+
// Scripted pill toggle — relay to HUD iframe
|
|
238
230
|
if (msg.type === 'WT_SCRIPTED_PILL_TOGGLE' && iframe && iframe.contentWindow) {
|
|
239
231
|
iframe.contentWindow.postMessage({ type: 'WT_SCRIPTED_PILL_TOGGLE', enabled: msg.enabled }, '*');
|
|
240
232
|
}
|
|
241
|
-
// Handle
|
|
233
|
+
// Handle agent thoughts in middle-down HUD
|
|
234
|
+
if (msg.type === 'WT_THOUGHT' || msg.type === 'Weavetab_THOUGHT') {
|
|
235
|
+
__wt_showThought(msg.text, msg);
|
|
236
|
+
}
|
|
237
|
+
if (msg.type === 'WT_CLEAR_THOUGHT' || msg.type === 'Weavetab_CLEAR_THOUGHT') {
|
|
238
|
+
__wt_removeThought();
|
|
239
|
+
}
|
|
240
|
+
// Handle incoming user notes from the extension
|
|
242
241
|
if (msg.type === 'WT_USER_NOTE_INJECT' || msg.type === 'WT_USER_NOTE') {
|
|
243
242
|
window.__wt_chat_queue = window.__wt_chat_queue || [];
|
|
244
243
|
let formattedMsg = msg.text || '';
|
|
@@ -299,7 +298,7 @@ function __wt_safeAppendToBody(el) {
|
|
|
299
298
|
|
|
300
299
|
// State persistence bridge: listen for state changes from iframe
|
|
301
300
|
window.addEventListener('message', function(e) {
|
|
302
|
-
// Forward relevant events to the extension background
|
|
301
|
+
// Forward relevant events to the extension background
|
|
303
302
|
if (e.data && (
|
|
304
303
|
e.data.type === 'WT_TOOL_CALL' ||
|
|
305
304
|
e.data.type === 'WT_PLAN_UPDATE' ||
|
|
@@ -477,133 +476,240 @@ function __wt_destroyBubble() {
|
|
|
477
476
|
__wt_lastRemoveTime = Date.now();
|
|
478
477
|
}
|
|
479
478
|
|
|
479
|
+
// ── MIDDLE-DOWN THOUGHT & PRESENCE HUD ─────────────────────────────
|
|
480
|
+
let __wt_thoughtHudEl = null;
|
|
481
|
+
let __wt_thoughtHudTimer = null;
|
|
482
|
+
let __wt_thoughtHudCountdown = null;
|
|
483
|
+
|
|
484
|
+
function __wt_highlightAnchor(anchor) {
|
|
485
|
+
if (!anchor) return;
|
|
486
|
+
try {
|
|
487
|
+
let sel = anchor;
|
|
488
|
+
if (anchor.startsWith('w:')) {
|
|
489
|
+
const stripped = anchor.slice(2);
|
|
490
|
+
sel = `[data-wt-id="${stripped}"]`;
|
|
491
|
+
}
|
|
492
|
+
const el = document.querySelector(sel) || (window.__Weavetab_shadowQuery ? window.__Weavetab_shadowQuery(sel) : null);
|
|
493
|
+
if (!el) return;
|
|
494
|
+
const r = el.getBoundingClientRect();
|
|
495
|
+
if (r.width === 0 && r.height === 0) return;
|
|
496
|
+
|
|
497
|
+
const ring = document.createElement('div');
|
|
498
|
+
ring.setAttribute('data-wt-ignore', 'true');
|
|
499
|
+
ring.style.cssText = `position:fixed;left:${r.left}px;top:${r.top}px;width:${r.width}px;height:${r.height}px;border:1.5px solid #38bdf8;box-shadow:0 0 16px rgba(56,189,248,0.5);border-radius:4px;z-index:2147483646;pointer-events:none;animation:wt-consider-pulse 1.2s ease-in-out infinite;`;
|
|
500
|
+
(document.getElementById('Weavetab-root')?.shadowRoot || document.body || document.documentElement).appendChild(ring);
|
|
501
|
+
setTimeout(() => {
|
|
502
|
+
ring.style.transition = 'opacity 0.25s ease-out';
|
|
503
|
+
ring.style.opacity = '0';
|
|
504
|
+
setTimeout(() => ring.remove(), 260);
|
|
505
|
+
}, 2400);
|
|
506
|
+
} catch(e) {}
|
|
507
|
+
}
|
|
508
|
+
|
|
480
509
|
function __wt_removeThought() {
|
|
481
|
-
if (
|
|
482
|
-
|
|
510
|
+
if (__wt_thoughtHudTimer) {
|
|
511
|
+
clearTimeout(__wt_thoughtHudTimer);
|
|
512
|
+
__wt_thoughtHudTimer = null;
|
|
513
|
+
}
|
|
514
|
+
if (__wt_thoughtHudCountdown) {
|
|
515
|
+
clearInterval(__wt_thoughtHudCountdown);
|
|
516
|
+
__wt_thoughtHudCountdown = null;
|
|
517
|
+
}
|
|
518
|
+
if (__wt_thoughtHudEl) {
|
|
519
|
+
const el = __wt_thoughtHudEl;
|
|
520
|
+
__wt_thoughtHudEl = null;
|
|
521
|
+
el.style.opacity = '0';
|
|
522
|
+
el.style.transform = 'translateX(-50%) translateY(10px)';
|
|
523
|
+
setTimeout(() => {
|
|
524
|
+
if (el.parentNode) el.remove();
|
|
525
|
+
}, 220);
|
|
526
|
+
}
|
|
527
|
+
__wt_feedbackSticky = false;
|
|
528
|
+
clearTimeout(window.__wt_feedbackStickyTimer);
|
|
483
529
|
__wt_destroyBubble();
|
|
484
530
|
}
|
|
485
531
|
|
|
486
532
|
function __wt_showThought(text, options) {
|
|
487
|
-
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
533
|
+
if (typeof __wt_masterVisualsEnabled !== 'undefined' && !__wt_masterVisualsEnabled) return;
|
|
534
|
+
if (!text || typeof text !== 'string') return;
|
|
490
535
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
}
|
|
536
|
+
const opts = options || {};
|
|
537
|
+
const isQuestion = opts.action === 'question' || opts.kind === 'question' || !!opts.ask;
|
|
538
|
+
const anchor = opts.anchor || '';
|
|
495
539
|
|
|
496
|
-
|
|
497
|
-
if (
|
|
498
|
-
|
|
499
|
-
setTimeout(function() { __wt_renderThought(next.text, next.options); }, 200);
|
|
540
|
+
// Contextual visual anchor highlight
|
|
541
|
+
if (anchor) {
|
|
542
|
+
__wt_highlightAnchor(anchor);
|
|
500
543
|
}
|
|
501
|
-
}
|
|
502
544
|
|
|
503
|
-
//
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
545
|
+
// Clear pending timers
|
|
546
|
+
if (__wt_thoughtHudTimer) {
|
|
547
|
+
clearTimeout(__wt_thoughtHudTimer);
|
|
548
|
+
__wt_thoughtHudTimer = null;
|
|
549
|
+
}
|
|
550
|
+
if (__wt_thoughtHudCountdown) {
|
|
551
|
+
clearInterval(__wt_thoughtHudCountdown);
|
|
552
|
+
__wt_thoughtHudCountdown = null;
|
|
553
|
+
}
|
|
507
554
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
__wt_askTimer = null;
|
|
537
|
-
if (__wt_askBridge) { __wt_askBridge.dataset.status = 'timeout'; __wt_askBridge.dataset.result = ''; }
|
|
538
|
-
__wt_removeAsk();
|
|
539
|
-
}
|
|
540
|
-
}, 1000);
|
|
541
|
-
|
|
542
|
-
// Smooth input row — delays slightly so bubble appears first, then input slides up
|
|
543
|
-
setTimeout(function() {
|
|
544
|
-
if (!__wt_askBridge) return;
|
|
545
|
-
|
|
546
|
-
var row = document.createElement('div');
|
|
547
|
-
row.setAttribute('data-wt-ignore', '');
|
|
548
|
-
row.style.cssText = 'position:fixed;bottom:16px;left:50%;transform:translateX(-50%) translateY(8px);z-index:2147483640;display:flex;align-items:center;gap:0;pointer-events:auto;opacity:0;transition:opacity 0.25s ease-out, transform 0.25s ease-out;';
|
|
549
|
-
|
|
550
|
-
var input;
|
|
551
|
-
if (inputType === 'paragraph') {
|
|
552
|
-
input = document.createElement('textarea');
|
|
553
|
-
input.rows = 3;
|
|
554
|
-
input.style.cssText = 'min-width:280px;max-width:480px;font-size:11px;padding:6px 8px;border-radius:4px 0 0 4px;background:#042f2e;color:#e4e4e7;border:1px solid #059669;border-right:none;outline:none;resize:vertical;font-family:"IBM Plex Mono",monospace;';
|
|
555
|
-
input.placeholder = 'Type your response...';
|
|
556
|
-
} else {
|
|
557
|
-
input = document.createElement('input');
|
|
558
|
-
input.style.cssText = 'min-width:200px;font-size:11px;padding:4px 8px;border-radius:4px 0 0 4px;background:#042f2e;color:#e4e4e7;border:1px solid #059669;border-right:none;outline:none;caret-color:#10b981;font-family:"IBM Plex Mono",monospace;';
|
|
559
|
-
input.placeholder = 'Your answer...';
|
|
560
|
-
}
|
|
555
|
+
let hud = __wt_thoughtHudEl;
|
|
556
|
+
if (!hud || !hud.parentNode) {
|
|
557
|
+
hud = document.createElement('div');
|
|
558
|
+
hud.id = '__wt_thought_hud';
|
|
559
|
+
hud.setAttribute('data-wt-ignore', 'true');
|
|
560
|
+
hud.style.cssText = `
|
|
561
|
+
position: fixed;
|
|
562
|
+
bottom: 24px;
|
|
563
|
+
left: 50%;
|
|
564
|
+
transform: translateX(-50%) translateY(8px);
|
|
565
|
+
z-index: 2147483647;
|
|
566
|
+
width: 320px;
|
|
567
|
+
max-width: calc(100vw - 32px);
|
|
568
|
+
background: #0b0d12;
|
|
569
|
+
border: 1px solid #1e222b;
|
|
570
|
+
border-radius: 4px;
|
|
571
|
+
padding: 10px 12px;
|
|
572
|
+
box-shadow: 0 10px 30px rgba(0,0,0,0.8), 0 0 1px rgba(255,255,255,0.08);
|
|
573
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Inter", sans-serif;
|
|
574
|
+
color: #f3f4f6;
|
|
575
|
+
pointer-events: auto;
|
|
576
|
+
opacity: 0;
|
|
577
|
+
transition: opacity 0.18s cubic-bezier(0.16, 1, 0.3, 1), transform 0.18s cubic-bezier(0.16, 1, 0.3, 1);
|
|
578
|
+
box-sizing: border-box;
|
|
579
|
+
`;
|
|
580
|
+
(document.getElementById('Weavetab-root')?.shadowRoot || document.body || document.documentElement).appendChild(hud);
|
|
581
|
+
__wt_thoughtHudEl = hud;
|
|
582
|
+
}
|
|
561
583
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
btn.textContent = 'Send';
|
|
584
|
+
const cleanText = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
585
|
+
const anchorBadge = anchor ? `<span style="color:#2b70ff;font-size:10px;font-family:monospace;font-weight:600;margin-left:4px;">@${anchor.replace(/&/g,'&')}</span>` : '';
|
|
565
586
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
587
|
+
if (isQuestion) {
|
|
588
|
+
const timeoutSec = (opts.timeout || (opts.ask && opts.ask.timeout) || 20);
|
|
589
|
+
hud.innerHTML = `
|
|
590
|
+
<div style="display:flex;align-items:flex-start;justify-content:space-between;gap:8px;margin-bottom:8px;">
|
|
591
|
+
<div style="font-size:12px;line-height:1.4;color:#ffffff;font-weight:500;word-break:break-word;">
|
|
592
|
+
${cleanText}${anchorBadge}
|
|
593
|
+
</div>
|
|
594
|
+
<button id="wt-hud-close" title="Dismiss" style="background:transparent;border:none;color:#555d6d;font-size:12px;cursor:pointer;padding:0 2px;line-height:1;margin-top:1px;">✕</button>
|
|
595
|
+
</div>
|
|
596
|
+
<div style="display:flex;align-items:center;gap:6px;">
|
|
597
|
+
<input id="wt-hud-input" type="text" placeholder="Type answer..." style="height:28px;background:#14161f;border:1px solid #252a36;border-radius:3px;padding:0 8px;font-size:12px;color:#fff;outline:none;flex:1;min-width:0;caret-color:#2b70ff;font-family:inherit;box-sizing:border-box;" />
|
|
598
|
+
<button id="wt-hud-submit-btn" title="Send" style="width:28px;height:28px;background:#2b70ff;border:none;border-radius:3px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;padding:0;box-sizing:border-box;">
|
|
599
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
|
600
|
+
</button>
|
|
601
|
+
<span id="wt-hud-countdown" style="font-size:10px;color:#64748b;font-family:monospace;margin-left:2px;min-width:20px;text-align:right;">${timeoutSec}s</span>
|
|
602
|
+
</div>
|
|
603
|
+
`;
|
|
604
|
+
} else {
|
|
605
|
+
// Feedback / observation mode — ultra compact single row
|
|
606
|
+
hud.innerHTML = `
|
|
607
|
+
<div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
|
|
608
|
+
<div style="display:flex;align-items:center;gap:7px;min-width:0;">
|
|
609
|
+
<span style="display:inline-block;width:5px;height:5px;border-radius:50%;background:#2b70ff;box-shadow:0 0 6px #2b70ff;flex-shrink:0;"></span>
|
|
610
|
+
<span style="font-size:12px;line-height:1.4;color:#f3f4f6;word-break:break-word;font-weight:450;">${cleanText}${anchorBadge}</span>
|
|
611
|
+
</div>
|
|
612
|
+
<button id="wt-hud-close" title="Dismiss" style="background:transparent;border:none;color:#555d6d;font-size:12px;cursor:pointer;padding:0 2px;line-height:1;flex-shrink:0;">✕</button>
|
|
613
|
+
</div>
|
|
614
|
+
`;
|
|
615
|
+
}
|
|
570
616
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
617
|
+
// Animate in
|
|
618
|
+
requestAnimationFrame(() => {
|
|
619
|
+
if (hud) {
|
|
620
|
+
hud.style.opacity = '1';
|
|
621
|
+
hud.style.transform = 'translateX(-50%) translateY(0)';
|
|
622
|
+
}
|
|
623
|
+
});
|
|
576
624
|
|
|
577
|
-
|
|
625
|
+
// Wire close button
|
|
626
|
+
const closeBtn = hud.querySelector('#wt-hud-close');
|
|
627
|
+
if (closeBtn) {
|
|
628
|
+
closeBtn.addEventListener('click', () => {
|
|
629
|
+
__wt_removeThought();
|
|
630
|
+
});
|
|
631
|
+
}
|
|
578
632
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
}
|
|
633
|
+
if (isQuestion) {
|
|
634
|
+
let askBridge = document.getElementById('__wt_ask_bridge');
|
|
635
|
+
if (!askBridge) {
|
|
636
|
+
askBridge = document.createElement('div');
|
|
637
|
+
askBridge.id = '__wt_ask_bridge';
|
|
638
|
+
askBridge.style.display = 'none';
|
|
639
|
+
document.body.appendChild(askBridge);
|
|
640
|
+
}
|
|
641
|
+
askBridge.dataset.status = 'pending';
|
|
642
|
+
askBridge.dataset.result = '';
|
|
643
|
+
|
|
644
|
+
const input = hud.querySelector('#wt-hud-input');
|
|
645
|
+
const submitBtn = hud.querySelector('#wt-hud-submit-btn');
|
|
646
|
+
const countdownSpan = hud.querySelector('#wt-hud-countdown');
|
|
647
|
+
|
|
648
|
+
let remaining = opts.timeout || (opts.ask && opts.ask.timeout) || 20;
|
|
649
|
+
|
|
650
|
+
__wt_thoughtHudCountdown = setInterval(() => {
|
|
651
|
+
remaining--;
|
|
652
|
+
if (countdownSpan) countdownSpan.textContent = `${remaining}s`;
|
|
653
|
+
if (remaining <= 0) {
|
|
654
|
+
clearInterval(__wt_thoughtHudCountdown);
|
|
655
|
+
__wt_thoughtHudCountdown = null;
|
|
656
|
+
if (askBridge) {
|
|
657
|
+
askBridge.dataset.status = 'timeout';
|
|
658
|
+
askBridge.dataset.result = '';
|
|
659
|
+
}
|
|
660
|
+
__wt_removeThought();
|
|
661
|
+
}
|
|
662
|
+
}, 1000);
|
|
587
663
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
if (
|
|
591
|
-
|
|
592
|
-
|
|
664
|
+
const submit = () => {
|
|
665
|
+
const val = input ? input.value.trim() : '';
|
|
666
|
+
if (askBridge) {
|
|
667
|
+
askBridge.dataset.status = 'submitted';
|
|
668
|
+
askBridge.dataset.result = val;
|
|
593
669
|
}
|
|
594
|
-
if (
|
|
670
|
+
if (window.__wt_ask_bridge && window.__wt_ask_bridge.resolve) {
|
|
671
|
+
window.__wt_ask_bridge.resolve({ success: true, response: val, status: 'answered' });
|
|
672
|
+
window.__wt_ask_bridge = {};
|
|
673
|
+
}
|
|
674
|
+
__wt_removeThought();
|
|
595
675
|
};
|
|
596
|
-
|
|
676
|
+
|
|
677
|
+
if (submitBtn) submitBtn.addEventListener('click', submit);
|
|
678
|
+
if (input) {
|
|
679
|
+
input.addEventListener('focus', () => { input.style.borderColor = '#2b70ff'; });
|
|
680
|
+
input.addEventListener('blur', () => { input.style.borderColor = '#252a36'; });
|
|
681
|
+
input.addEventListener('keydown', (e) => {
|
|
682
|
+
if (e.key === 'Enter') submit();
|
|
683
|
+
if (e.key === 'Escape') __wt_removeThought();
|
|
684
|
+
});
|
|
685
|
+
setTimeout(() => { if (input) input.focus(); }, 80);
|
|
686
|
+
}
|
|
687
|
+
} else {
|
|
688
|
+
// Auto-fade timer for feedback
|
|
689
|
+
const autoDuration = Math.max(3800, Math.min(8000, text.length * 50));
|
|
690
|
+
__wt_thoughtHudTimer = setTimeout(() => {
|
|
691
|
+
__wt_removeThought();
|
|
692
|
+
}, autoDuration);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
function __wt_renderThought(text, options) {
|
|
697
|
+
__wt_showThought(text, options);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
function __wt_processThoughtQueue() {
|
|
701
|
+
if (__wt_thoughtQueue.length > 0) {
|
|
702
|
+
var next = __wt_thoughtQueue.shift();
|
|
703
|
+
setTimeout(function() { __wt_showThought(next.text, next.options); }, 200);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function __wt_showQuestion(text, inputType, timeoutSeconds) {
|
|
708
|
+
__wt_showThought(text, { action: 'question', timeout: timeoutSeconds || 20 });
|
|
597
709
|
}
|
|
598
710
|
|
|
599
711
|
function __wt_removeAsk() {
|
|
600
|
-
|
|
601
|
-
if (__wt_askContainer) { __wt_askContainer.remove(); __wt_askContainer = null; }
|
|
602
|
-
__wt_askBridge = null;
|
|
603
|
-
__wt_feedbackSticky = false;
|
|
604
|
-
clearTimeout(window.__wt_feedbackStickyTimer);
|
|
605
|
-
__wt_thoughtQueue = [];
|
|
606
|
-
__wt_destroyBubble();
|
|
712
|
+
__wt_removeThought();
|
|
607
713
|
}
|
|
608
714
|
|
|
609
715
|
// ── SHARED OVERLAY CONTAINER ────────────────────────────────────
|
|
@@ -960,6 +1066,33 @@ class WeaveCursor {
|
|
|
960
1066
|
|
|
961
1067
|
const shadow = this._host.attachShadow({ mode: 'closed' });
|
|
962
1068
|
|
|
1069
|
+
// Liquid trail canvas inside shadow root (zero DOM reflows)
|
|
1070
|
+
this._trailCanvas = document.createElement('canvas');
|
|
1071
|
+
this._trailCanvas.setAttribute('data-wt-ignore', 'true');
|
|
1072
|
+
Object.assign(this._trailCanvas.style, {
|
|
1073
|
+
position: 'fixed',
|
|
1074
|
+
top: '0',
|
|
1075
|
+
left: '0',
|
|
1076
|
+
width: '100vw',
|
|
1077
|
+
height: '100vh',
|
|
1078
|
+
pointerEvents: 'none',
|
|
1079
|
+
zIndex: '2147483645',
|
|
1080
|
+
overflow: 'visible',
|
|
1081
|
+
});
|
|
1082
|
+
this._trailCanvas.width = typeof window !== 'undefined' && window.innerWidth ? window.innerWidth : 1920;
|
|
1083
|
+
this._trailCanvas.height = typeof window !== 'undefined' && window.innerHeight ? window.innerHeight : 1080;
|
|
1084
|
+
shadow.appendChild(this._trailCanvas);
|
|
1085
|
+
this._trailCtx = this._trailCanvas.getContext('2d');
|
|
1086
|
+
this._trailPoints = [];
|
|
1087
|
+
this._lastTrailRecord = 0;
|
|
1088
|
+
|
|
1089
|
+
window.addEventListener('resize', () => {
|
|
1090
|
+
if (this._trailCanvas) {
|
|
1091
|
+
this._trailCanvas.width = window.innerWidth;
|
|
1092
|
+
this._trailCanvas.height = window.innerHeight;
|
|
1093
|
+
}
|
|
1094
|
+
});
|
|
1095
|
+
|
|
963
1096
|
// Hotspot aligned with the top-left pointer tip (3.0, 5.0 in 32x32 viewBox)
|
|
964
1097
|
this._hotX = 3.0;
|
|
965
1098
|
this._hotY = 5.0;
|
|
@@ -1043,6 +1176,9 @@ class WeaveCursor {
|
|
|
1043
1176
|
if (typeof __wt_masterVisualsEnabled !== 'undefined' && !__wt_masterVisualsEnabled) {
|
|
1044
1177
|
this._visible = false;
|
|
1045
1178
|
this._cursor.style.opacity = '0';
|
|
1179
|
+
if (this._trailCtx && this._trailCanvas) {
|
|
1180
|
+
this._trailCtx.clearRect(0, 0, this._trailCanvas.width, this._trailCanvas.height);
|
|
1181
|
+
}
|
|
1046
1182
|
return;
|
|
1047
1183
|
}
|
|
1048
1184
|
this._visible = visible;
|
|
@@ -1140,7 +1276,7 @@ class WeaveCursor {
|
|
|
1140
1276
|
}
|
|
1141
1277
|
}
|
|
1142
1278
|
|
|
1143
|
-
this._render();
|
|
1279
|
+
this._render(currentTime);
|
|
1144
1280
|
}
|
|
1145
1281
|
|
|
1146
1282
|
this._animFrame = requestAnimationFrame(draw);
|
|
@@ -1149,15 +1285,66 @@ class WeaveCursor {
|
|
|
1149
1285
|
this._animFrame = requestAnimationFrame(draw);
|
|
1150
1286
|
}
|
|
1151
1287
|
|
|
1152
|
-
_render() {
|
|
1288
|
+
_render(currentTime) {
|
|
1153
1289
|
if (typeof __wt_masterVisualsEnabled !== 'undefined' && !__wt_masterVisualsEnabled) {
|
|
1154
1290
|
this._cursor.style.opacity = '0';
|
|
1291
|
+
if (this._trailCtx && this._trailCanvas) {
|
|
1292
|
+
this._trailCtx.clearRect(0, 0, this._trailCanvas.width, this._trailCanvas.height);
|
|
1293
|
+
}
|
|
1155
1294
|
return;
|
|
1156
1295
|
}
|
|
1157
1296
|
const x = this._lerpX;
|
|
1158
1297
|
const y = this._lerpY;
|
|
1159
1298
|
if (x === -9999 || y === -9999) return;
|
|
1160
|
-
|
|
1299
|
+
|
|
1300
|
+
const now = currentTime || performance.now();
|
|
1301
|
+
|
|
1302
|
+
// 1. Trail decay tracking
|
|
1303
|
+
const dx = this._targetX - this._lerpX;
|
|
1304
|
+
const dy = this._targetY - this._lerpY;
|
|
1305
|
+
const moveDist = Math.sqrt(dx * dx + dy * dy);
|
|
1306
|
+
|
|
1307
|
+
if (moveDist > 1.8 && now - this._lastTrailRecord > 22) {
|
|
1308
|
+
this._trailPoints.push({ x, y, birth: now });
|
|
1309
|
+
this._lastTrailRecord = now;
|
|
1310
|
+
if (this._trailPoints.length > 14) this._trailPoints.shift();
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
// Render decaying trail
|
|
1314
|
+
if (this._trailCtx && this._trailCanvas) {
|
|
1315
|
+
this._trailCtx.clearRect(0, 0, this._trailCanvas.width, this._trailCanvas.height);
|
|
1316
|
+
for (let i = this._trailPoints.length - 1; i >= 0; i--) {
|
|
1317
|
+
const pt = this._trailPoints[i];
|
|
1318
|
+
const age = (now - pt.birth) / 260;
|
|
1319
|
+
if (age >= 1) {
|
|
1320
|
+
this._trailPoints.splice(i, 1);
|
|
1321
|
+
continue;
|
|
1322
|
+
}
|
|
1323
|
+
const alpha = (1 - age) * 0.45;
|
|
1324
|
+
const radius = Math.max(1, (1 - age) * 2.8);
|
|
1325
|
+
this._trailCtx.beginPath();
|
|
1326
|
+
this._trailCtx.arc(pt.x, pt.y, radius, 0, Math.PI * 2);
|
|
1327
|
+
this._trailCtx.fillStyle = `rgba(18, 104, 255, ${alpha})`;
|
|
1328
|
+
this._trailCtx.shadowColor = '#1268ff';
|
|
1329
|
+
this._trailCtx.shadowBlur = 4;
|
|
1330
|
+
this._trailCtx.fill();
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
// 2. Cursor scale and tactile micro-physics
|
|
1335
|
+
let targetScale = this._scale;
|
|
1336
|
+
if (this._state === 'clicking') {
|
|
1337
|
+
targetScale = this._scale * 0.82; // Tactile compression on click
|
|
1338
|
+
} else if (this._state === 'hover') {
|
|
1339
|
+
targetScale = this._scale * 1.08; // Interactive focus
|
|
1340
|
+
} else if (this._state === 'idle') {
|
|
1341
|
+
targetScale = this._scale + Math.sin(now * 0.003) * 0.012; // Alive breathing oscillation
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// 3. Dynamic velocity tilt (natural motion lag)
|
|
1345
|
+
const tilt = Math.max(-5, Math.min(5, dx * 0.06));
|
|
1346
|
+
|
|
1347
|
+
this._cursor.style.transform = `translate3d(${x - this._hotX}px, ${y - this._hotY}px, 0) rotate(${tilt}deg) scale(${targetScale})`;
|
|
1161
1348
|
}
|
|
1162
1349
|
}
|
|
1163
1350
|
|
|
@@ -1175,16 +1362,24 @@ function moveCursor(x, y, state) {
|
|
|
1175
1362
|
}
|
|
1176
1363
|
}
|
|
1177
1364
|
|
|
1178
|
-
|
|
1179
|
-
// Click ripple (kept as page-level effect, not inside shadow DOM)
|
|
1365
|
+
// Enhanced twin action ripples radiating from click target
|
|
1180
1366
|
function ripple(x, y) {
|
|
1181
1367
|
if (typeof __wt_masterVisualsEnabled !== 'undefined' && !__wt_masterVisualsEnabled) return;
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1368
|
+
const host = document.createElement('div');
|
|
1369
|
+
host.className = 'Weavetab-ripple-host';
|
|
1370
|
+
host.setAttribute('data-wt-ignore', 'true');
|
|
1371
|
+
host.style.cssText = `position:fixed;left:${x}px;top:${y}px;pointer-events:none;z-index:2147483646;transform:translate(-50%, -50%);`;
|
|
1372
|
+
|
|
1373
|
+
const w1 = document.createElement('div');
|
|
1374
|
+
w1.style.cssText = 'position:absolute;top:50%;left:50%;width:8px;height:8px;margin:-4px 0 0 -4px;border:2px solid #1268ff;border-radius:50%;box-shadow:0 0 12px rgba(18,104,255,0.7);animation:__wt_ripple_expand 0.42s cubic-bezier(0.1, 0.8, 0.3, 1) forwards;pointer-events:none;';
|
|
1375
|
+
|
|
1376
|
+
const w2 = document.createElement('div');
|
|
1377
|
+
w2.style.cssText = 'position:absolute;top:50%;left:50%;width:8px;height:8px;margin:-4px 0 0 -4px;border:1.5px solid #60a5fa;border-radius:50%;animation:__wt_ripple_expand 0.52s 0.08s cubic-bezier(0.1, 0.8, 0.3, 1) forwards;pointer-events:none;';
|
|
1378
|
+
|
|
1379
|
+
host.appendChild(w1);
|
|
1380
|
+
host.appendChild(w2);
|
|
1381
|
+
(document.getElementById('Weavetab-root')?.shadowRoot || document.body || document.documentElement).appendChild(host);
|
|
1382
|
+
setTimeout(() => host.remove(), 620);
|
|
1188
1383
|
}
|
|
1189
1384
|
|
|
1190
1385
|
// ── X-RAY SPOTLIGHT OVERLAY (Phase 5.2) ────────────────────────
|
|
@@ -1703,78 +1898,21 @@ function __wt_handleWeavetabMsg(msg) {
|
|
|
1703
1898
|
setTimeout(function(){ __wt_feedbackSticky = false; }, 2000);
|
|
1704
1899
|
}
|
|
1705
1900
|
|
|
1706
|
-
// stickyFeedback=true: fired by Weavetab_logs when agent answers a user question.
|
|
1707
|
-
// Pin the bubble for 10s so tool chatter (moving to..., typing...) cannot override it.
|
|
1708
|
-
if (msg.stickyFeedback === true && msg.hud && msg.hud.action) {
|
|
1709
|
-
__wt_thoughtQueue = [];
|
|
1710
|
-
clearTimeout(window.__wt_feedbackStickyTimer);
|
|
1711
|
-
|
|
1712
|
-
if (msg.ask) {
|
|
1713
|
-
window.__wt_feedbackStickyTimer = setTimeout(function(){
|
|
1714
|
-
__wt_feedbackSticky = false;
|
|
1715
|
-
__wt_removeAsk();
|
|
1716
|
-
}, (msg.ask.timeout || 120) * 1000 + 2000);
|
|
1717
|
-
__wt_showQuestion(msg.hud.action, msg.ask.input || 'sentence', msg.ask.timeout || 120);
|
|
1718
|
-
} else {
|
|
1719
|
-
__wt_feedbackSticky = true;
|
|
1720
|
-
window.__wt_feedbackStickyTimer = setTimeout(function(){
|
|
1721
|
-
__wt_feedbackSticky = false;
|
|
1722
|
-
__wt_destroyBubble();
|
|
1723
|
-
}, 10000);
|
|
1724
|
-
__wt_renderThought(msg.hud.action, { active: false, sticky: true });
|
|
1725
|
-
if (msg.hud) updateHUD(msg.hud.action, msg.hud.detail);
|
|
1726
|
-
}
|
|
1727
|
-
if (msg.cursor) {
|
|
1728
|
-
__wt_lastCursor = { x: msg.cursor.x, y: msg.cursor.y };
|
|
1729
|
-
if (msg.cursor.waypoints && msg.cursor.duration_ms) {
|
|
1730
|
-
__weaveCursor.setWaypoints(msg.cursor.waypoints, msg.cursor.duration_ms);
|
|
1731
|
-
}
|
|
1732
|
-
moveCursor(msg.cursor.x, msg.cursor.y, msg.state);
|
|
1733
|
-
}
|
|
1734
|
-
else if (msg.state) { moveCursor(__wt_lastCursor.x, __wt_lastCursor.y, msg.state); }
|
|
1735
|
-
return;
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
1901
|
if (msg.hud) {
|
|
1739
1902
|
updateHUD(msg.hud.action, msg.hud.detail);
|
|
1740
1903
|
var a = (msg.hud.action || '').trim();
|
|
1741
1904
|
if (a === 'reading the page...') {
|
|
1742
|
-
__wt_showReadingGlow();
|
|
1743
|
-
__wt_showThought('Reading the page...', { active: true });
|
|
1744
1905
|
__weaveCursor.setState('reading');
|
|
1745
1906
|
} else if (a === 'Mission Running') {
|
|
1746
|
-
// Tool call is starting — switch to eval animation and show tool bubble
|
|
1747
1907
|
__wt_toolActive = true;
|
|
1748
1908
|
__weaveCursor.setState('eval');
|
|
1749
|
-
__wt_showThought('Executing tool...', { active: true });
|
|
1750
1909
|
} else if (a.startsWith('[OK]')) {
|
|
1751
|
-
// Tool completed successfully — revert to idle and instantly hide bubble
|
|
1752
1910
|
__weaveCursor.setState('idle');
|
|
1753
1911
|
__wt_toolActive = false;
|
|
1754
|
-
if (!__wt_feedbackSticky) {
|
|
1755
|
-
__wt_destroyBubble(); // Instant removal
|
|
1756
|
-
__wt_processThoughtQueue();
|
|
1757
|
-
}
|
|
1758
1912
|
} else if (a.startsWith('[ERR]')) {
|
|
1759
|
-
// Tool errored — show stuck cursor briefly
|
|
1760
1913
|
__weaveCursor.setState('stuck');
|
|
1761
1914
|
__wt_toolActive = false;
|
|
1762
1915
|
setTimeout(function(){ __weaveCursor.setState('idle'); }, 3000);
|
|
1763
|
-
if (!__wt_feedbackSticky) {
|
|
1764
|
-
__wt_destroyBubble(); // Instant removal
|
|
1765
|
-
__wt_processThoughtQueue();
|
|
1766
|
-
}
|
|
1767
|
-
} else if (a && a.length > 3) {
|
|
1768
|
-
__wt_hideReadingGlow();
|
|
1769
|
-
if (!__wt_feedbackSticky) {
|
|
1770
|
-
__wt_showThought(a, { active: true });
|
|
1771
|
-
}
|
|
1772
|
-
} else {
|
|
1773
|
-
if (!__wt_feedbackSticky) {
|
|
1774
|
-
__wt_hideReadingGlow();
|
|
1775
|
-
__wt_destroyBubble(); // Instant removal
|
|
1776
|
-
__wt_processThoughtQueue();
|
|
1777
|
-
}
|
|
1778
1916
|
}
|
|
1779
1917
|
}
|
|
1780
1918
|
if (msg.cursor || msg.hud) {
|
|
@@ -1782,6 +1920,14 @@ function __wt_handleWeavetabMsg(msg) {
|
|
|
1782
1920
|
}
|
|
1783
1921
|
}
|
|
1784
1922
|
|
|
1923
|
+
// Pure thought event from browser_thoughts tool only
|
|
1924
|
+
if (msg.type === 'WT_THOUGHT' || msg.type === 'Weavetab_THOUGHT') {
|
|
1925
|
+
__wt_showThought(msg.text, msg);
|
|
1926
|
+
}
|
|
1927
|
+
if (msg.type === 'WT_CLEAR_THOUGHT' || msg.type === 'Weavetab_CLEAR_THOUGHT') {
|
|
1928
|
+
__wt_removeThought();
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1785
1931
|
// Handle plan updates via sendToExtension channel
|
|
1786
1932
|
if (msg.type === 'Weavetab_STATE' && msg.plan) {
|
|
1787
1933
|
const p = msg.plan;
|
|
@@ -2050,741 +2196,8 @@ function setFaviconHref(dataUrl) {
|
|
|
2050
2196
|
|
|
2051
2197
|
|
|
2052
2198
|
|
|
2053
|
-
// ──
|
|
2054
|
-
// Design inspired by designs/elements.html
|
|
2055
|
-
(function initWeaveTabUI() {
|
|
2056
|
-
if (window.self !== window.top) return;
|
|
2057
|
-
if (document.getElementById('wt-main-container')) return;
|
|
2058
|
-
|
|
2059
|
-
const version = "2.5.0";
|
|
2060
|
-
const isBeta = true;
|
|
2061
|
-
|
|
2062
|
-
// ── CSS Injection ─────────────────────────────────────────────
|
|
2063
|
-
const style = document.createElement('style');
|
|
2064
|
-
style.id = 'wt-ui-styles';
|
|
2065
|
-
style.textContent = `
|
|
2066
|
-
/* ── Sidepanel Tokens ────────────────────────────────────── */
|
|
2067
|
-
:host, .wt-sp-root { all: initial; }
|
|
2068
|
-
.wt-sp-root, .wt-sp-root * { box-sizing: border-box; margin: 0; padding: 0; }
|
|
2069
|
-
|
|
2070
|
-
.wt-sp-root {
|
|
2071
|
-
--sp-bg: #ffffff;
|
|
2072
|
-
--sp-bg-panel: #f9f9fb;
|
|
2073
|
-
--sp-bg-item: #f4f4f5;
|
|
2074
|
-
--sp-bg-hover: #e8e8ec;
|
|
2075
|
-
--sp-border: #e4e4e7;
|
|
2076
|
-
--sp-border-hi: #d4d4d8;
|
|
2077
|
-
--sp-text: #18181b;
|
|
2078
|
-
--sp-text-secondary: #52525b;
|
|
2079
|
-
--sp-text-muted: #a1a1aa;
|
|
2080
|
-
--sp-blue: #3b82f6;
|
|
2081
|
-
--sp-blue-light: #60a5fa;
|
|
2082
|
-
--sp-green: #16a34a;
|
|
2083
|
-
--sp-green-bg: #f0fdf4;
|
|
2084
|
-
--sp-red: #ef4444;
|
|
2085
|
-
--sp-red-bg: #fef2f2;
|
|
2086
|
-
--sp-yellow: #f59e0b;
|
|
2087
|
-
--sp-shadow: 0 1px 3px rgba(0,0,0,0.08), 0 4px 12px rgba(0,0,0,0.06);
|
|
2088
|
-
--sp-font: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', system-ui, sans-serif;
|
|
2089
|
-
--sp-font-mono: 'SF Mono', 'Cascadia Code', 'Consolas', monospace;
|
|
2090
|
-
}
|
|
2091
|
-
|
|
2092
|
-
.wt-sp-root[data-theme='dark'] {
|
|
2093
|
-
--sp-bg: #09090b;
|
|
2094
|
-
--sp-bg-panel: #111113;
|
|
2095
|
-
--sp-bg-item: #1c1c1f;
|
|
2096
|
-
--sp-bg-hover: #27272a;
|
|
2097
|
-
--sp-border: #27272a;
|
|
2098
|
-
--sp-border-hi: #3f3f46;
|
|
2099
|
-
--sp-text: #fafafa;
|
|
2100
|
-
--sp-text-secondary: #a1a1aa;
|
|
2101
|
-
--sp-text-muted: #52525b;
|
|
2102
|
-
--sp-green-bg: #052e16;
|
|
2103
|
-
--sp-red-bg: #450a0a;
|
|
2104
|
-
--sp-shadow: 0 1px 3px rgba(0,0,0,0.4), 0 4px 12px rgba(0,0,0,0.3);
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
|
-
/* ── Panel Shell ─────────────────────────────────────────── */
|
|
2108
|
-
.wt-sp-root {
|
|
2109
|
-
position: fixed;
|
|
2110
|
-
top: 0; bottom: 0; right: 0;
|
|
2111
|
-
width: 360px;
|
|
2112
|
-
display: none !important;
|
|
2113
|
-
flex-direction: column;
|
|
2114
|
-
background: var(--sp-bg);
|
|
2115
|
-
border-left: 1px solid var(--sp-border);
|
|
2116
|
-
z-index: 2147483646;
|
|
2117
|
-
pointer-events: auto;
|
|
2118
|
-
font-family: var(--sp-font);
|
|
2119
|
-
color: var(--sp-text);
|
|
2120
|
-
|
|
2121
|
-
transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
|
|
2122
|
-
overflow: hidden;
|
|
2123
|
-
}
|
|
2124
|
-
|
|
2125
|
-
.wt-sp-root.minimized {
|
|
2126
|
-
transform: translateX(100%);
|
|
2127
|
-
pointer-events: none;
|
|
2128
|
-
}
|
|
2129
|
-
|
|
2130
|
-
/* ── Header ──────────────────────────────────────────────── */
|
|
2131
|
-
.wt-sp-header {
|
|
2132
|
-
display: flex;
|
|
2133
|
-
justify-content: space-between;
|
|
2134
|
-
align-items: center;
|
|
2135
|
-
padding: 10px 14px;
|
|
2136
|
-
border-bottom: 1px solid var(--sp-border);
|
|
2137
|
-
flex-shrink: 0;
|
|
2138
|
-
-webkit-app-region: drag;
|
|
2139
|
-
}
|
|
2140
|
-
|
|
2141
|
-
.wt-sp-brand {
|
|
2142
|
-
font-size: 13px;
|
|
2143
|
-
font-weight: 600;
|
|
2144
|
-
color: var(--sp-text);
|
|
2145
|
-
letter-spacing: -0.01em;
|
|
2146
|
-
}
|
|
2147
|
-
|
|
2148
|
-
.wt-sp-controls {
|
|
2149
|
-
display: flex;
|
|
2150
|
-
align-items: center;
|
|
2151
|
-
gap: 2px;
|
|
2152
|
-
-webkit-app-region: no-drag;
|
|
2153
|
-
}
|
|
2154
|
-
|
|
2155
|
-
.wt-sp-ctrl-btn {
|
|
2156
|
-
width: 28px; height: 28px;
|
|
2157
|
-
display: flex; align-items: center; justify-content: center;
|
|
2158
|
-
background: transparent;
|
|
2159
|
-
border: none;
|
|
2160
|
-
border-radius: 6px;
|
|
2161
|
-
color: var(--sp-text-muted);
|
|
2162
|
-
cursor: pointer;
|
|
2163
|
-
transition: background 0.15s, color 0.15s;
|
|
2164
|
-
font-size: 14px;
|
|
2165
|
-
}
|
|
2166
|
-
.wt-sp-ctrl-btn:hover { background: var(--sp-bg-hover); color: var(--sp-text); }
|
|
2167
|
-
|
|
2168
|
-
/* ── Badge Row ───────────────────────────────────────────── */
|
|
2169
|
-
.wt-sp-badges {
|
|
2170
|
-
display: flex;
|
|
2171
|
-
align-items: center;
|
|
2172
|
-
gap: 6px;
|
|
2173
|
-
padding: 6px 14px;
|
|
2174
|
-
border-bottom: 1px solid var(--sp-border);
|
|
2175
|
-
flex-shrink: 0;
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
.wt-sp-badge {
|
|
2179
|
-
font-size: 9px;
|
|
2180
|
-
font-weight: 600;
|
|
2181
|
-
padding: 2px 6px;
|
|
2182
|
-
border-radius: 4px;
|
|
2183
|
-
text-transform: uppercase;
|
|
2184
|
-
letter-spacing: 0.03em;
|
|
2185
|
-
}
|
|
2186
|
-
.wt-sp-badge-dev { background: var(--sp-blue); color: #fff; }
|
|
2187
|
-
.wt-sp-badge-beta { background: var(--sp-yellow); color: #fff; }
|
|
2188
|
-
|
|
2189
|
-
/* ── Body (scrollable) ───────────────────────────────────── */
|
|
2190
|
-
.wt-sp-body {
|
|
2191
|
-
flex: 1;
|
|
2192
|
-
overflow-y: auto;
|
|
2193
|
-
display: flex;
|
|
2194
|
-
flex-direction: column;
|
|
2195
|
-
}
|
|
2196
|
-
|
|
2197
|
-
.wt-sp-body::-webkit-scrollbar { width: 5px; }
|
|
2198
|
-
.wt-sp-body::-webkit-scrollbar-track { background: transparent; }
|
|
2199
|
-
.wt-sp-body::-webkit-scrollbar-thumb { background: var(--sp-border-hi); border-radius: 3px; }
|
|
2200
|
-
|
|
2201
|
-
/* ── Section ─────────────────────────────────────────────── */
|
|
2202
|
-
.wt-sp-section {
|
|
2203
|
-
border-bottom: 1px solid var(--sp-border);
|
|
2204
|
-
}
|
|
2205
|
-
|
|
2206
|
-
.wt-sp-section-hdr {
|
|
2207
|
-
display: flex;
|
|
2208
|
-
align-items: center;
|
|
2209
|
-
gap: 6px;
|
|
2210
|
-
padding: 8px 14px;
|
|
2211
|
-
font-size: 11px;
|
|
2212
|
-
font-weight: 600;
|
|
2213
|
-
color: var(--sp-text-secondary);
|
|
2214
|
-
text-transform: uppercase;
|
|
2215
|
-
letter-spacing: 0.04em;
|
|
2216
|
-
cursor: pointer;
|
|
2217
|
-
user-select: none;
|
|
2218
|
-
transition: color 0.15s;
|
|
2219
|
-
}
|
|
2220
|
-
.wt-sp-section-hdr:hover { color: var(--sp-text); }
|
|
2221
|
-
|
|
2222
|
-
.wt-sp-chevron {
|
|
2223
|
-
font-size: 10px;
|
|
2224
|
-
transition: transform 0.2s ease;
|
|
2225
|
-
display: inline-block;
|
|
2226
|
-
color: var(--sp-text-muted);
|
|
2227
|
-
}
|
|
2228
|
-
.wt-sp-section.closed .wt-sp-chevron { transform: rotate(-90deg); }
|
|
2229
|
-
|
|
2230
|
-
.wt-sp-section-body {
|
|
2231
|
-
overflow: hidden;
|
|
2232
|
-
transition: max-height 0.25s cubic-bezier(0.32, 0.72, 0, 1);
|
|
2233
|
-
max-height: 500px;
|
|
2234
|
-
}
|
|
2235
|
-
.wt-sp-section.closed .wt-sp-section-body { max-height: 0; }
|
|
2236
|
-
|
|
2237
|
-
.wt-sp-section-grow { flex: 1; display: flex; flex-direction: column; }
|
|
2238
|
-
.wt-sp-section-grow .wt-sp-section-body { flex: 1; overflow-y: auto; max-height: none; }
|
|
2239
|
-
|
|
2240
|
-
/* ── Tasks ────────────────────────────────────────────────── */
|
|
2241
|
-
.wt-sp-tasks {
|
|
2242
|
-
display: flex;
|
|
2243
|
-
flex-direction: column;
|
|
2244
|
-
padding: 0 14px 10px;
|
|
2245
|
-
gap: 2px;
|
|
2246
|
-
}
|
|
2247
|
-
|
|
2248
|
-
.wt-sp-task {
|
|
2249
|
-
display: flex;
|
|
2250
|
-
align-items: flex-start;
|
|
2251
|
-
gap: 8px;
|
|
2252
|
-
padding: 6px 8px;
|
|
2253
|
-
border-radius: 6px;
|
|
2254
|
-
font-size: 12px;
|
|
2255
|
-
line-height: 1.4;
|
|
2256
|
-
cursor: pointer;
|
|
2257
|
-
transition: background 0.15s;
|
|
2258
|
-
}
|
|
2259
|
-
.wt-sp-task:hover { background: var(--sp-bg-hover); }
|
|
2260
|
-
|
|
2261
|
-
.wt-sp-task.done { color: var(--sp-green); }
|
|
2262
|
-
.wt-sp-task.active { color: var(--sp-text); background: var(--sp-bg-item); border-left: 2px solid var(--sp-blue); padding-left: 6px; }
|
|
2263
|
-
.wt-sp-task.pending { color: var(--sp-text-muted); }
|
|
2264
|
-
|
|
2265
|
-
.wt-sp-task-icon { flex-shrink: 0; width: 16px; text-align: center; font-size: 11px; margin-top: 1px; }
|
|
2266
|
-
.wt-sp-task.done .wt-sp-task-icon { color: var(--sp-green); }
|
|
2267
|
-
.wt-sp-task.active .wt-sp-task-icon { color: var(--sp-blue); }
|
|
2268
|
-
|
|
2269
|
-
.wt-sp-task-desc { flex: 1; word-break: break-word; }
|
|
2270
|
-
.wt-sp-task.done .wt-sp-task-desc { text-decoration: line-through; opacity: 0.7; }
|
|
2271
|
-
|
|
2272
|
-
.wt-sp-task-empty {
|
|
2273
|
-
font-size: 11px;
|
|
2274
|
-
color: var(--sp-text-muted);
|
|
2275
|
-
padding: 8px;
|
|
2276
|
-
text-align: center;
|
|
2277
|
-
}
|
|
2278
|
-
|
|
2279
|
-
/* ── Activity Log ────────────────────────────────────────── */
|
|
2280
|
-
.wt-sp-log {
|
|
2281
|
-
display: flex;
|
|
2282
|
-
flex-direction: column;
|
|
2283
|
-
gap: 1px;
|
|
2284
|
-
padding: 0 14px 10px;
|
|
2285
|
-
font-family: var(--sp-font-mono);
|
|
2286
|
-
}
|
|
2287
|
-
|
|
2288
|
-
.wt-sp-log-entry {
|
|
2289
|
-
display: flex;
|
|
2290
|
-
align-items: flex-start;
|
|
2291
|
-
gap: 8px;
|
|
2292
|
-
padding: 5px 8px;
|
|
2293
|
-
border-radius: 4px;
|
|
2294
|
-
font-size: 11px;
|
|
2295
|
-
line-height: 1.4;
|
|
2296
|
-
transition: background 0.1s;
|
|
2297
|
-
}
|
|
2298
|
-
.wt-sp-log-entry:hover { background: var(--sp-bg-hover); }
|
|
2299
|
-
|
|
2300
|
-
.wt-sp-log-icon { flex-shrink: 0; width: 14px; text-align: center; margin-top: 1px; font-size: 10px; }
|
|
2301
|
-
.wt-sp-log-icon.running { color: var(--sp-blue); }
|
|
2302
|
-
.wt-sp-log-icon.done { color: var(--sp-green); }
|
|
2303
|
-
.wt-sp-log-icon.error { color: var(--sp-red); }
|
|
2304
|
-
|
|
2305
|
-
.wt-sp-log-name {
|
|
2306
|
-
font-weight: 500;
|
|
2307
|
-
color: var(--sp-text);
|
|
2308
|
-
white-space: nowrap;
|
|
2309
|
-
overflow: hidden;
|
|
2310
|
-
text-overflow: ellipsis;
|
|
2311
|
-
max-width: 140px;
|
|
2312
|
-
}
|
|
2313
|
-
|
|
2314
|
-
.wt-sp-log-badge {
|
|
2315
|
-
font-size: 9px;
|
|
2316
|
-
font-weight: 600;
|
|
2317
|
-
padding: 1px 5px;
|
|
2318
|
-
border-radius: 3px;
|
|
2319
|
-
text-transform: uppercase;
|
|
2320
|
-
letter-spacing: 0.02em;
|
|
2321
|
-
flex-shrink: 0;
|
|
2322
|
-
}
|
|
2323
|
-
.wt-sp-log-badge.running { background: rgba(59,130,246,0.12); color: var(--sp-blue); }
|
|
2324
|
-
.wt-sp-log-badge.done { background: rgba(22,163,74,0.12); color: var(--sp-green); }
|
|
2325
|
-
.wt-sp-log-badge.error { background: rgba(239,68,68,0.12); color: var(--sp-red); }
|
|
2326
|
-
.wt-sp-log-badge.info { background: var(--sp-bg-item); color: var(--sp-text-muted); }
|
|
2327
|
-
|
|
2328
|
-
.wt-sp-log-time {
|
|
2329
|
-
font-size: 10px;
|
|
2330
|
-
color: var(--sp-text-muted);
|
|
2331
|
-
margin-left: auto;
|
|
2332
|
-
flex-shrink: 0;
|
|
2333
|
-
}
|
|
2334
|
-
|
|
2335
|
-
.wt-sp-log-empty {
|
|
2336
|
-
font-size: 11px;
|
|
2337
|
-
color: var(--sp-text-muted);
|
|
2338
|
-
padding: 8px;
|
|
2339
|
-
text-align: center;
|
|
2340
|
-
font-family: var(--sp-font);
|
|
2341
|
-
}
|
|
2342
|
-
|
|
2343
|
-
/* ── Chat ─────────────────────────────────────────────────── */
|
|
2344
|
-
.wt-sp-chat {
|
|
2345
|
-
padding: 10px 14px;
|
|
2346
|
-
border-top: 1px solid var(--sp-border);
|
|
2347
|
-
flex-shrink: 0;
|
|
2348
|
-
}
|
|
2349
|
-
|
|
2350
|
-
.wt-sp-chat-row {
|
|
2351
|
-
display: flex;
|
|
2352
|
-
gap: 6px;
|
|
2353
|
-
align-items: flex-end;
|
|
2354
|
-
}
|
|
2355
|
-
|
|
2356
|
-
.wt-sp-chat-input {
|
|
2357
|
-
flex: 1;
|
|
2358
|
-
padding: 8px 12px;
|
|
2359
|
-
background: var(--sp-bg-item);
|
|
2360
|
-
border: 1px solid var(--sp-border);
|
|
2361
|
-
border-radius: 8px;
|
|
2362
|
-
color: var(--sp-text);
|
|
2363
|
-
font-family: var(--sp-font);
|
|
2364
|
-
font-size: 12px;
|
|
2365
|
-
outline: none;
|
|
2366
|
-
resize: none;
|
|
2367
|
-
min-height: 36px;
|
|
2368
|
-
max-height: 100px;
|
|
2369
|
-
transition: border-color 0.15s;
|
|
2370
|
-
line-height: 1.4;
|
|
2371
|
-
}
|
|
2372
|
-
.wt-sp-chat-input::placeholder { color: var(--sp-text-muted); }
|
|
2373
|
-
.wt-sp-chat-input:focus { border-color: var(--sp-blue); }
|
|
2374
|
-
|
|
2375
|
-
.wt-sp-send-btn {
|
|
2376
|
-
width: 36px; height: 36px;
|
|
2377
|
-
display: flex; align-items: center; justify-content: center;
|
|
2378
|
-
background: var(--sp-blue);
|
|
2379
|
-
border: none;
|
|
2380
|
-
border-radius: 8px;
|
|
2381
|
-
cursor: pointer;
|
|
2382
|
-
flex-shrink: 0;
|
|
2383
|
-
transition: background 0.15s, transform 0.1s;
|
|
2384
|
-
}
|
|
2385
|
-
.wt-sp-send-btn:hover { background: #2563eb; }
|
|
2386
|
-
.wt-sp-send-btn:active { transform: scale(0.95); }
|
|
2387
|
-
.wt-sp-send-btn.sent { background: var(--sp-green); }
|
|
2388
|
-
.wt-sp-send-btn svg { width: 16px; height: 16px; stroke: #fff; fill: none; }
|
|
2389
|
-
|
|
2390
|
-
/* ── Debug Section ───────────────────────────────────────── */
|
|
2391
|
-
.wt-sp-debug-area {
|
|
2392
|
-
padding: 0 14px 10px;
|
|
2393
|
-
position: relative;
|
|
2394
|
-
min-height: 200px;
|
|
2395
|
-
}
|
|
2396
|
-
|
|
2397
|
-
.wt-sp-f3-btn {
|
|
2398
|
-
margin-left: auto;
|
|
2399
|
-
font-size: 9px;
|
|
2400
|
-
font-weight: 600;
|
|
2401
|
-
padding: 2px 6px;
|
|
2402
|
-
border-radius: 4px;
|
|
2403
|
-
background: var(--sp-bg-item);
|
|
2404
|
-
border: 1px solid var(--sp-border);
|
|
2405
|
-
color: var(--sp-text-muted);
|
|
2406
|
-
cursor: pointer;
|
|
2407
|
-
text-transform: uppercase;
|
|
2408
|
-
transition: all 0.15s;
|
|
2409
|
-
}
|
|
2410
|
-
.wt-sp-f3-btn:hover { color: var(--sp-text); border-color: var(--sp-border-hi); }
|
|
2411
|
-
|
|
2412
|
-
/* ── System Icon (minimized state) ───────────────────────── */
|
|
2413
|
-
#wt-system-icon {
|
|
2414
|
-
position: fixed;
|
|
2415
|
-
bottom: 20px;
|
|
2416
|
-
right: 20px;
|
|
2417
|
-
width: 40px;
|
|
2418
|
-
height: 40px;
|
|
2419
|
-
background: var(--sp-bg);
|
|
2420
|
-
border: 1px solid var(--sp-border);
|
|
2421
|
-
border-radius: 10px;
|
|
2422
|
-
display: none;
|
|
2423
|
-
justify-content: center;
|
|
2424
|
-
align-items: center;
|
|
2425
|
-
cursor: pointer;
|
|
2426
|
-
z-index: 2147483640;
|
|
2427
|
-
box-shadow: var(--sp-shadow);
|
|
2428
|
-
transition: background 0.15s, transform 0.15s;
|
|
2429
|
-
pointer-events: auto;
|
|
2430
|
-
}
|
|
2431
|
-
#wt-system-icon:hover { background: var(--sp-bg-hover); transform: scale(1.05); }
|
|
2432
|
-
#wt-system-icon svg { width: 18px; height: 18px; fill: var(--sp-text-muted); }
|
|
2433
|
-
|
|
2434
|
-
/* ── Utilities ────────────────────────────────────────────── */
|
|
2435
|
-
.wt-sp-root .hidden, .wt-sp-root.hidden, .wt-hidden { display: none !important; }
|
|
2436
|
-
|
|
2437
|
-
@keyframes wt-sp-spin {
|
|
2438
|
-
from { transform: rotate(0deg); }
|
|
2439
|
-
to { transform: rotate(360deg); }
|
|
2440
|
-
}
|
|
2441
|
-
.wt-sp-spinner {
|
|
2442
|
-
display: inline-block;
|
|
2443
|
-
width: 10px; height: 10px;
|
|
2444
|
-
border: 1.5px solid var(--sp-border-hi);
|
|
2445
|
-
border-top-color: var(--sp-blue);
|
|
2446
|
-
border-radius: 50%;
|
|
2447
|
-
animation: wt-sp-spin 0.8s linear infinite;
|
|
2448
|
-
}
|
|
2449
|
-
`;
|
|
2450
|
-
(document.head || document.documentElement).appendChild(style);
|
|
2451
|
-
|
|
2452
|
-
// ── HTML Construction ─────────────────────────────────────────
|
|
2453
|
-
const container = document.createElement('div');
|
|
2454
|
-
container.id = 'wt-main-container';
|
|
2455
|
-
container.className = 'wt-sp-root';
|
|
2456
|
-
container.setAttribute('data-wt-ignore', 'true');
|
|
2457
|
-
container.setAttribute('data-theme', 'dark');
|
|
2458
|
-
|
|
2459
|
-
container.innerHTML = `
|
|
2460
|
-
<div class="wt-sp-header">
|
|
2461
|
-
<span class="wt-sp-brand">Weavetab</span>
|
|
2462
|
-
<div class="wt-sp-controls">
|
|
2463
|
-
<button class="wt-sp-ctrl-btn" id="wt-theme-toggle" title="Toggle theme">
|
|
2464
|
-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>
|
|
2465
|
-
</button>
|
|
2466
|
-
<button class="wt-sp-ctrl-btn" id="wt-minimize-btn" title="Minimize">
|
|
2467
|
-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14"/></svg>
|
|
2468
|
-
</button>
|
|
2469
|
-
</div>
|
|
2470
|
-
</div>
|
|
2471
|
-
<div class="wt-sp-badges">
|
|
2472
|
-
<span class="wt-sp-badge wt-sp-badge-dev hidden" id="wt-badge-dev">DEV</span>
|
|
2473
|
-
${isBeta ? '<span class="wt-sp-badge wt-sp-badge-beta">BETA</span>' : ''}
|
|
2474
|
-
</div>
|
|
2475
|
-
<div class="wt-sp-body">
|
|
2476
|
-
<div class="wt-sp-section" id="wt-sec-tasks">
|
|
2477
|
-
<div class="wt-sp-section-hdr" id="wt-header-tasks">
|
|
2478
|
-
<span class="wt-sp-chevron">›</span>
|
|
2479
|
-
<span>Tasks</span>
|
|
2480
|
-
</div>
|
|
2481
|
-
<div class="wt-sp-section-body">
|
|
2482
|
-
<div class="wt-sp-tasks" id="wt-todo-list">
|
|
2483
|
-
<div class="wt-sp-task-empty">No active mission</div>
|
|
2484
|
-
</div>
|
|
2485
|
-
</div>
|
|
2486
|
-
</div>
|
|
2487
|
-
|
|
2488
|
-
<div class="wt-sp-section wt-sp-section-grow" id="wt-sec-logs">
|
|
2489
|
-
<div class="wt-sp-section-hdr" id="wt-header-logs">
|
|
2490
|
-
<span class="wt-sp-chevron">›</span>
|
|
2491
|
-
<span>Activity</span>
|
|
2492
|
-
</div>
|
|
2493
|
-
<div class="wt-sp-section-body">
|
|
2494
|
-
<div class="wt-sp-log" id="wt-log-container">
|
|
2495
|
-
<div class="wt-sp-log-empty">Waiting for activity...</div>
|
|
2496
|
-
</div>
|
|
2497
|
-
</div>
|
|
2498
|
-
</div>
|
|
2499
|
-
|
|
2500
|
-
<div class="wt-sp-section closed" id="wt-sec-debug">
|
|
2501
|
-
<div class="wt-sp-section-hdr" id="wt-header-debug">
|
|
2502
|
-
<span class="wt-sp-chevron">›</span>
|
|
2503
|
-
<span>Debug</span>
|
|
2504
|
-
</div>
|
|
2505
|
-
<div class="wt-sp-section-body">
|
|
2506
|
-
<div class="wt-sp-debug-area" id="wt-debug-content-area"></div>
|
|
2507
|
-
</div>
|
|
2508
|
-
</div>
|
|
2509
|
-
</div>
|
|
2510
|
-
|
|
2511
|
-
<div class="wt-sp-chat">
|
|
2512
|
-
<div class="wt-sp-chat-row">
|
|
2513
|
-
<textarea class="wt-sp-chat-input" id="wt-msg-input" placeholder="Send feedback..." rows="1"></textarea>
|
|
2514
|
-
<button class="wt-sp-send-btn" id="wt-send-btn">
|
|
2515
|
-
<svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>
|
|
2516
|
-
</button>
|
|
2517
|
-
</div>
|
|
2518
|
-
</div>
|
|
2519
|
-
`;
|
|
2520
|
-
__wt_safeAppendToBody(container);
|
|
2521
|
-
|
|
2522
|
-
const systemIcon = document.createElement('div');
|
|
2523
|
-
systemIcon.id = 'wt-system-icon';
|
|
2524
|
-
systemIcon.title = 'Open Weavetab';
|
|
2525
|
-
systemIcon.innerHTML = `
|
|
2526
|
-
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
2527
|
-
<path d="M4 4h16v16H4V4zm2 2v12h12V6H6zm2 3h3v2H8V9zm4 4h4v2h-4v-2z" />
|
|
2528
|
-
</svg>
|
|
2529
|
-
`;
|
|
2530
|
-
__wt_safeAppendToBody(systemIcon);
|
|
2531
|
-
|
|
2532
|
-
// ── PERSISTENT ACTIVITY LOG ──────────────────────────────────
|
|
2533
|
-
// Logs never clear until browser close — append-only like Claude Chrome
|
|
2534
|
-
window.__wt_logEntries = [];
|
|
2535
|
-
const logContainer = document.getElementById('wt-log-container');
|
|
2536
|
-
|
|
2537
|
-
function __wt_addLogEntry(name, status, detail) {
|
|
2538
|
-
const entry = {
|
|
2539
|
-
name: name || 'unknown',
|
|
2540
|
-
status: status || 'info',
|
|
2541
|
-
detail: detail || '',
|
|
2542
|
-
time: Date.now()
|
|
2543
|
-
};
|
|
2544
|
-
window.__wt_logEntries.push(entry);
|
|
2545
|
-
__wt_renderLogEntry(entry);
|
|
2546
|
-
// Auto-scroll to bottom
|
|
2547
|
-
if (logContainer) {
|
|
2548
|
-
logContainer.scrollTop = logContainer.scrollHeight;
|
|
2549
|
-
}
|
|
2550
|
-
}
|
|
2551
|
-
|
|
2552
|
-
function __wt_renderLogEntry(entry) {
|
|
2553
|
-
if (!logContainer) return;
|
|
2554
|
-
// Remove empty placeholder on first real entry
|
|
2555
|
-
const empty = logContainer.querySelector('.wt-sp-log-empty');
|
|
2556
|
-
if (empty) empty.remove();
|
|
2557
|
-
|
|
2558
|
-
const el = document.createElement('div');
|
|
2559
|
-
el.className = 'wt-sp-log-entry';
|
|
2560
|
-
|
|
2561
|
-
const iconClass = entry.status === 'done' ? 'done' : entry.status === 'error' ? 'error' : entry.status === 'running' ? 'running' : '';
|
|
2562
|
-
const icon = entry.status === 'running' ? '<span class="wt-sp-spinner"></span>'
|
|
2563
|
-
: entry.status === 'done' ? '✓'
|
|
2564
|
-
: entry.status === 'error' ? '✗'
|
|
2565
|
-
: '●';
|
|
2566
|
-
|
|
2567
|
-
const badge = entry.status === 'running' ? 'RUNNING'
|
|
2568
|
-
: entry.status === 'done' ? 'OK'
|
|
2569
|
-
: entry.status === 'error' ? 'ERR'
|
|
2570
|
-
: '';
|
|
2571
|
-
|
|
2572
|
-
const timeStr = new Date(entry.time).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
2573
|
-
|
|
2574
|
-
el.innerHTML = `
|
|
2575
|
-
<span class="wt-sp-log-icon ${iconClass}">${icon}</span>
|
|
2576
|
-
<span class="wt-sp-log-name">${__wt_escapeHtml(entry.name)}</span>
|
|
2577
|
-
${badge ? `<span class="wt-sp-log-badge ${entry.status}">${badge}</span>` : ''}
|
|
2578
|
-
<span class="wt-sp-log-time">${timeStr}</span>
|
|
2579
|
-
`;
|
|
2580
|
-
|
|
2581
|
-
if (entry.detail) {
|
|
2582
|
-
const detailEl = document.createElement('div');
|
|
2583
|
-
detailEl.style.cssText = 'width:100%;font-size:10px;color:var(--sp-text-muted);white-space:pre-wrap;word-break:break-all;margin-top:2px;';
|
|
2584
|
-
detailEl.textContent = entry.detail;
|
|
2585
|
-
el.appendChild(detailEl);
|
|
2586
|
-
}
|
|
2587
|
-
|
|
2588
|
-
logContainer.appendChild(el);
|
|
2589
|
-
}
|
|
2590
|
-
|
|
2591
|
-
function __wt_escapeHtml(str) {
|
|
2592
|
-
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
2593
|
-
}
|
|
2594
|
-
|
|
2595
|
-
// ── THEME SYSTEM ──────────────────────────────────────────────
|
|
2596
|
-
function __wt_applyTheme(theme) {
|
|
2597
|
-
container.setAttribute('data-theme', theme);
|
|
2598
|
-
document.getElementById('wt-system-icon') && document.getElementById('wt-system-icon').setAttribute('data-theme', theme);
|
|
2599
|
-
try { browserAPI.storage.local.set({ wt_theme: theme }); } catch(e) {}
|
|
2600
|
-
}
|
|
2601
|
-
|
|
2602
|
-
function __wt_toggleTheme() {
|
|
2603
|
-
const current = container.getAttribute('data-theme');
|
|
2604
|
-
__wt_applyTheme(current === 'dark' ? 'light' : 'dark');
|
|
2605
|
-
}
|
|
2606
|
-
|
|
2607
|
-
// Restore persisted theme
|
|
2608
|
-
try {
|
|
2609
|
-
browserAPI.storage.local.get(['wt_theme'], function(res) {
|
|
2610
|
-
if (res.wt_theme) {
|
|
2611
|
-
__wt_applyTheme(res.wt_theme);
|
|
2612
|
-
}
|
|
2613
|
-
});
|
|
2614
|
-
} catch(e) {}
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
// ── HUD STATUS INTERCEPTION (for activity log) ────────────────
|
|
2619
|
-
// Capture Weavetab_STATE hud updates and add to log
|
|
2620
|
-
window.addEventListener('message', function(e) {
|
|
2621
|
-
if (e.data && e.data.type === 'Weavetab-msg-in' && e.data.data && e.data.data.type === 'Weavetab_STATE' && e.data.data.hud) {
|
|
2622
|
-
const hud = e.data.data.hud;
|
|
2623
|
-
if (hud.action && hud.action.length > 2) {
|
|
2624
|
-
__wt_addLogEntry(hud.action, 'info', hud.detail || '');
|
|
2625
|
-
}
|
|
2626
|
-
}
|
|
2627
|
-
});
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
// ── Panel State Persistence ────────────────────────────────────
|
|
2632
|
-
// Sidepanel always opens on browser launch (background clears state on startup).
|
|
2633
|
-
// Persists minimized state across page navigations within a session.
|
|
2634
|
-
function minimizePanel() {
|
|
2635
|
-
container.classList.add('minimized');
|
|
2636
|
-
systemIcon.style.display = 'flex';
|
|
2637
|
-
try { browserAPI.storage.local.set({ wt_panel_minimized: true }); } catch(e) {}
|
|
2638
|
-
}
|
|
2639
|
-
|
|
2640
|
-
function restorePanel() {
|
|
2641
|
-
systemIcon.style.display = 'none';
|
|
2642
|
-
container.classList.remove('minimized');
|
|
2643
|
-
try { browserAPI.storage.local.set({ wt_panel_minimized: false }); } catch(e) {}
|
|
2644
|
-
}
|
|
2645
|
-
|
|
2646
|
-
// Restore minimized state from storage (respects user's last action)
|
|
2647
|
-
try {
|
|
2648
|
-
browserAPI.storage.local.get(['wt_panel_minimized'], function(res) {
|
|
2649
|
-
if (res.wt_panel_minimized) {
|
|
2650
|
-
container.classList.add('minimized');
|
|
2651
|
-
systemIcon.style.display = 'flex';
|
|
2652
|
-
}
|
|
2653
|
-
});
|
|
2654
|
-
} catch(e) {}
|
|
2655
|
-
|
|
2656
|
-
function toggleSection(id) {
|
|
2657
|
-
document.getElementById(id).classList.toggle('closed');
|
|
2658
|
-
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
function syncDevMode() {
|
|
2663
|
-
const active = !!window.__wt_devMode;
|
|
2664
|
-
const devBadge = document.getElementById('wt-badge-dev');
|
|
2665
|
-
|
|
2666
|
-
if (devBadge) devBadge.classList.toggle('hidden', !active);
|
|
2667
|
-
}
|
|
2668
|
-
|
|
2669
|
-
window.addEventListener('wt-config-sync', syncDevMode);
|
|
2670
|
-
|
|
2671
|
-
container.querySelector('#wt-minimize-btn').onclick = minimizePanel;
|
|
2672
|
-
systemIcon.onclick = restorePanel;
|
|
2673
|
-
container.querySelector('#wt-theme-toggle').onclick = __wt_toggleTheme;
|
|
2674
|
-
container.querySelector('#wt-header-tasks').onclick = () => toggleSection('wt-sec-tasks');
|
|
2675
|
-
container.querySelector('#wt-header-logs').onclick = () => toggleSection('wt-sec-logs');
|
|
2676
|
-
container.querySelector('#wt-header-debug').onclick = () => toggleSection('wt-sec-debug');
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
syncDevMode();
|
|
2680
|
-
|
|
2681
|
-
const msgInput = container.querySelector('#wt-msg-input');
|
|
2682
|
-
const sendBtn = container.querySelector('#wt-send-btn');
|
|
2683
|
-
|
|
2684
|
-
// Auto-resize textarea
|
|
2685
|
-
msgInput.addEventListener('input', function() {
|
|
2686
|
-
this.style.height = 'auto';
|
|
2687
|
-
this.style.height = Math.min(this.scrollHeight, 100) + 'px';
|
|
2688
|
-
});
|
|
2689
|
-
|
|
2690
|
-
// ── Plan Rendering Integration ───────────────────────────────
|
|
2691
|
-
function renderPlan(action, goal, tasks) {
|
|
2692
|
-
const list = document.getElementById('wt-todo-list');
|
|
2693
|
-
if (!list) return;
|
|
2694
|
-
|
|
2695
|
-
if (action === 'hide' || (!goal && (!tasks || tasks.length === 0))) {
|
|
2696
|
-
list.innerHTML = '<div class="wt-sp-task-empty">No active mission</div>';
|
|
2697
|
-
return;
|
|
2698
|
-
}
|
|
2699
|
-
|
|
2700
|
-
list.innerHTML = '';
|
|
2701
|
-
if (goal) {
|
|
2702
|
-
const goalEl = document.createElement('div');
|
|
2703
|
-
goalEl.className = 'wt-sp-task active';
|
|
2704
|
-
goalEl.style.cssText = 'margin-bottom:4px;font-weight:500;';
|
|
2705
|
-
goalEl.innerHTML = '<span class="wt-sp-task-icon">▶</span><span class="wt-sp-task-desc">' + __wt_escapeHtml(goal) + '</span>';
|
|
2706
|
-
list.appendChild(goalEl);
|
|
2707
|
-
}
|
|
2708
|
-
if (tasks && tasks.length > 0) {
|
|
2709
|
-
tasks.forEach(task => {
|
|
2710
|
-
const item = document.createElement('div');
|
|
2711
|
-
const statusClass = task.status === 'done' ? 'done' : (task.status === 'in-progress' ? 'active' : 'pending');
|
|
2712
|
-
const icon = task.status === 'done' ? '✓' : (task.status === 'in-progress' ? '<span class="wt-sp-spinner"></span>' : '○');
|
|
2713
|
-
|
|
2714
|
-
item.className = 'wt-sp-task ' + statusClass;
|
|
2715
|
-
item.setAttribute('data-task-id', task.id);
|
|
2716
|
-
item.innerHTML = '<span class="wt-sp-task-icon">' + icon + '</span><span class="wt-sp-task-desc">' + __wt_escapeHtml(task.description) + '</span>';
|
|
2717
|
-
|
|
2718
|
-
list.appendChild(item);
|
|
2719
|
-
});
|
|
2720
|
-
}
|
|
2721
|
-
|
|
2722
|
-
// Log the plan update
|
|
2723
|
-
__wt_addLogEntry('Plan updated', 'info', (tasks ? tasks.length : 0) + ' tasks');
|
|
2724
|
-
}
|
|
2725
|
-
|
|
2726
|
-
window.__wt_plan = renderPlan;
|
|
2727
|
-
|
|
2728
|
-
window.addEventListener('message', (e) => {
|
|
2729
|
-
if (e.data && e.data.type === '__WT_PLAN') {
|
|
2730
|
-
renderPlan(e.data.action, e.data.goal, e.data.tasks);
|
|
2731
|
-
}
|
|
2732
|
-
syncDevMode();
|
|
2733
|
-
});
|
|
2734
|
-
|
|
2735
|
-
setInterval(syncDevMode, 2000);
|
|
2736
|
-
|
|
2737
|
-
try {
|
|
2738
|
-
browserAPI.storage.local.get(['wt_plan_collapsed'], function(res) {});
|
|
2739
|
-
} catch(e) {}
|
|
2740
|
-
|
|
2741
|
-
// Persist draft
|
|
2742
|
-
msgInput.addEventListener('input', function() {
|
|
2743
|
-
try { browserAPI.storage.local.set({ wt_chat_draft: msgInput.value }); } catch(e) {}
|
|
2744
|
-
});
|
|
2745
|
-
|
|
2746
|
-
// Submit
|
|
2747
|
-
function submitFeedback() {
|
|
2748
|
-
var text = msgInput.value.trim();
|
|
2749
|
-
if (!text) return;
|
|
2750
|
-
|
|
2751
|
-
window.postMessage({
|
|
2752
|
-
type: '__WT_FEEDBACK',
|
|
2753
|
-
text: text
|
|
2754
|
-
}, '*');
|
|
2755
|
-
|
|
2756
|
-
window.dispatchEvent(new CustomEvent('Weavetab-msg-in', {
|
|
2757
|
-
detail: {
|
|
2758
|
-
type: 'USER_FEEDBACK',
|
|
2759
|
-
text: text
|
|
2760
|
-
}
|
|
2761
|
-
}));
|
|
2762
|
-
|
|
2763
|
-
try {
|
|
2764
|
-
var existing = JSON.parse(localStorage.getItem('__wt_chat_queue_persist') || '[]');
|
|
2765
|
-
existing.push({ text: text, ts: Date.now() });
|
|
2766
|
-
if (existing.length > 20) existing.splice(0, existing.length - 20);
|
|
2767
|
-
localStorage.setItem('__wt_chat_queue_persist', JSON.stringify(existing));
|
|
2768
|
-
} catch(e) {}
|
|
2769
|
-
|
|
2770
|
-
__wt_addLogEntry('Feedback sent', 'done', text.length > 60 ? text.substring(0, 60) + '...' : text);
|
|
2771
|
-
|
|
2772
|
-
msgInput.value = '';
|
|
2773
|
-
msgInput.style.height = 'auto';
|
|
2774
|
-
try { browserAPI.storage.local.remove('wt_chat_draft'); } catch(e) {}
|
|
2775
|
-
sendBtn.classList.add('sent');
|
|
2776
|
-
setTimeout(function(){ sendBtn.classList.remove('sent'); }, 1200);
|
|
2777
|
-
}
|
|
2778
|
-
|
|
2779
|
-
sendBtn.onclick = submitFeedback;
|
|
2780
|
-
msgInput.addEventListener('keydown', function(e) {
|
|
2781
|
-
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); submitFeedback(); }
|
|
2782
|
-
if (e.key === 'Escape') { minimizePanel(); }
|
|
2783
|
-
});
|
|
2784
|
-
|
|
2785
|
-
})();
|
|
2199
|
+
// ── SIDE PANEL REMOVED (Replaced by pure middle-down Thought HUD) ──
|
|
2786
2200
|
|
|
2787
|
-
// ── GEMINI-STYLE AREA SNIPE & DIRECT ANNOTATION ENGINE ─────────────────────
|
|
2788
2201
|
(function initAreaSnipeEngine() {
|
|
2789
2202
|
let isSnipeActive = false;
|
|
2790
2203
|
let currentSnipeMode = 'dom_target';
|
|
@@ -3051,7 +2464,7 @@ function setFaviconHref(dataUrl) {
|
|
|
3051
2464
|
}
|
|
3052
2465
|
}
|
|
3053
2466
|
|
|
3054
|
-
// Listen for
|
|
2467
|
+
// Listen for snipe trigger from background
|
|
3055
2468
|
browserAPI.runtime.onMessage.addListener((msg) => {
|
|
3056
2469
|
if (msg.type === 'WT_START_SNIPE') {
|
|
3057
2470
|
createOverlay(msg.mode || 'dom_target');
|