mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-05-18 14:53:36 +00:00
Add Browser settings for the default starting page and tool-result autofocus, and wire them through config, APIs, runtime opens, and the settings UI. Resolve Chrome extension __MSG_* manifest labels from locale metadata so installed extensions show readable names. Stabilize Browser viewport negotiation across canvas and modal surfaces by clearing stale frames, waiting for stable surface dimensions, and forcing sync after dock transitions. Move Browser loading/error state into a thin bottom status bar so it no longer overlays the page viewport.
355 lines
11 KiB
HTML
355 lines
11 KiB
HTML
<html>
|
|
<head>
|
|
<title>Browser Settings</title>
|
|
<script type="module">
|
|
import { store } from "/plugins/_browser/webui/browser-config-store.js";
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
<div x-data>
|
|
<template x-if="$store.browserConfig && config">
|
|
<div
|
|
class="browser-config-sections"
|
|
x-init="$store.browserConfig.init(config)"
|
|
x-effect="$store.browserConfig.bindConfig(config)"
|
|
x-destroy="$store.browserConfig.cleanup()"
|
|
>
|
|
<div class="browser-config-card">
|
|
<div class="section-title">Browsing</div>
|
|
<div class="section-description">
|
|
Set how new Browser sessions start and whether agent activity should pull focus.
|
|
</div>
|
|
|
|
<label class="browser-config-field">
|
|
<span class="browser-config-field-label">Starting page</span>
|
|
<input
|
|
type="text"
|
|
x-model="$store.browserConfig.config.default_homepage"
|
|
placeholder="about:blank or https://example.com"
|
|
autocomplete="off"
|
|
/>
|
|
</label>
|
|
|
|
<label class="browser-config-switch-row">
|
|
<span class="browser-config-switch-copy">
|
|
<span class="browser-config-field-label">Autofocus active page</span>
|
|
<span class="browser-config-field-help">Focus pages opened or changed by Browser tool results.</span>
|
|
</span>
|
|
<span class="browser-config-toggle-with-label">
|
|
<span class="browser-config-toggle-label" x-text="$store.browserConfig.autofocusLabel()"></span>
|
|
<span class="browser-config-toggle">
|
|
<input
|
|
type="checkbox"
|
|
:checked="$store.browserConfig.config.autofocus_active_page !== false"
|
|
@change="$store.browserConfig.setAutofocusActivePage($event.target.checked)"
|
|
/>
|
|
<span class="browser-config-switch"></span>
|
|
</span>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="browser-config-card">
|
|
<div class="section-title">Extensions</div>
|
|
<div class="section-description">
|
|
Choose which installed Chrome extensions Browser loads.
|
|
</div>
|
|
|
|
<div class="browser-config-warning">
|
|
<span class="material-symbols-outlined">warning</span>
|
|
<span>
|
|
Extensions run inside the Docker browser sandbox, but malicious or buggy extensions can
|
|
still damage that environment. Keep only the extensions you trust enabled.
|
|
</span>
|
|
</div>
|
|
|
|
<div class="browser-config-extension-list">
|
|
<div class="browser-config-subtitle">
|
|
<span>Installed extensions</span>
|
|
<span class="material-symbols-outlined spinning" x-show="$store.browserConfig.extensionsLoading">progress_activity</span>
|
|
</div>
|
|
<template x-if="!$store.browserConfig.extensionsLoading && !$store.browserConfig.extensionsList.length">
|
|
<div class="browser-config-empty">No installed extensions found.</div>
|
|
</template>
|
|
<template x-for="extension in $store.browserConfig.extensionsList" :key="extension.path">
|
|
<label class="browser-config-extension-row" :title="extension.path">
|
|
<span class="browser-config-extension-text">
|
|
<span class="browser-config-extension-name" x-text="extension.name || 'Unnamed extension'"></span>
|
|
<span class="browser-config-extension-meta" x-text="$store.browserConfig.extensionVersionLabel(extension)"></span>
|
|
</span>
|
|
<span class="browser-config-toggle">
|
|
<input
|
|
type="checkbox"
|
|
:checked="$store.browserConfig.extensionEnabled(extension)"
|
|
@change="$store.browserConfig.setExtensionEnabled(extension, $event.target.checked)"
|
|
/>
|
|
<span class="browser-config-switch"></span>
|
|
</span>
|
|
</label>
|
|
</template>
|
|
<div class="browser-config-note" x-show="$store.browserConfig.extensionsError">
|
|
<span class="material-symbols-outlined">error</span>
|
|
<span x-text="$store.browserConfig.extensionsError"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="browser-config-pill-row">
|
|
<span class="browser-config-pill" x-text="$store.browserConfig.pathCountLabel()"></span>
|
|
<span class="browser-config-pill tone-active" x-show="$store.browserConfig.extensionModeReady()">
|
|
Ready
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
|
|
<style>
|
|
.browser-config-sections {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
|
|
.browser-config-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14px;
|
|
padding: 16px;
|
|
border: 1px solid var(--color-border);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.browser-config-field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.browser-config-field-label {
|
|
color: var(--color-text);
|
|
font-size: 0.84rem;
|
|
font-weight: 650;
|
|
}
|
|
|
|
.browser-config-field-help {
|
|
color: var(--color-text-secondary);
|
|
font-size: 0.78rem;
|
|
line-height: 1.35;
|
|
}
|
|
|
|
.browser-config-field input[type="text"] {
|
|
width: 100%;
|
|
min-height: 36px;
|
|
padding: 7px 10px;
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 74%, transparent);
|
|
border-radius: 8px;
|
|
background: var(--color-input);
|
|
color: var(--color-text);
|
|
font: inherit;
|
|
}
|
|
|
|
.browser-config-switch-row {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
align-items: center;
|
|
gap: 16px;
|
|
min-height: 46px;
|
|
padding-top: 2px;
|
|
}
|
|
|
|
.browser-config-switch-copy {
|
|
display: flex;
|
|
min-width: 0;
|
|
flex-direction: column;
|
|
gap: 3px;
|
|
}
|
|
|
|
.browser-config-toggle-with-label {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.browser-config-toggle-label {
|
|
min-width: 24px;
|
|
color: var(--color-text-secondary);
|
|
font-size: 0.78rem;
|
|
font-weight: 650;
|
|
text-align: right;
|
|
}
|
|
|
|
.browser-config-extension-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
padding: 12px;
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);
|
|
border-radius: 8px;
|
|
background: color-mix(in srgb, var(--color-panel) 78%, transparent);
|
|
}
|
|
|
|
.browser-config-subtitle {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 8px;
|
|
color: var(--color-text-secondary);
|
|
font-size: 0.82rem;
|
|
font-weight: 650;
|
|
}
|
|
|
|
.browser-config-subtitle .material-symbols-outlined {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.browser-config-empty,
|
|
.browser-config-extension-meta {
|
|
color: var(--color-text-secondary);
|
|
font-size: 0.78rem;
|
|
}
|
|
|
|
.browser-config-extension-row {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
align-items: center;
|
|
gap: 14px;
|
|
min-height: 42px;
|
|
padding: 8px 0;
|
|
}
|
|
|
|
.browser-config-extension-row + .browser-config-extension-row {
|
|
border-top: 1px solid color-mix(in srgb, var(--color-border) 52%, transparent);
|
|
}
|
|
|
|
.browser-config-extension-text {
|
|
display: flex;
|
|
min-width: 0;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.browser-config-extension-name {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
color: var(--color-text);
|
|
font-weight: 650;
|
|
}
|
|
|
|
.browser-config-toggle {
|
|
position: relative;
|
|
display: inline-flex;
|
|
flex: 0 0 auto;
|
|
align-items: center;
|
|
width: 42px;
|
|
height: 24px;
|
|
}
|
|
|
|
.browser-config-toggle input {
|
|
position: absolute;
|
|
inset: 0;
|
|
margin: 0;
|
|
opacity: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.browser-config-switch {
|
|
width: 100%;
|
|
height: 100%;
|
|
border-radius: 999px;
|
|
background: color-mix(in srgb, var(--color-border) 78%, transparent);
|
|
pointer-events: none;
|
|
transition: background-color 0.18s cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
|
|
.browser-config-switch::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 3px;
|
|
left: 3px;
|
|
width: 18px;
|
|
height: 18px;
|
|
border-radius: 50%;
|
|
background: var(--color-background);
|
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24);
|
|
transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
|
|
.browser-config-toggle input:checked + .browser-config-switch {
|
|
background: color-mix(in srgb, var(--color-primary) 76%, #16a34a);
|
|
}
|
|
|
|
.browser-config-toggle input:checked + .browser-config-switch::after {
|
|
transform: translateX(18px);
|
|
}
|
|
|
|
.browser-config-note {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 8px;
|
|
padding: 10px 12px;
|
|
border-radius: 8px;
|
|
background: color-mix(in srgb, var(--color-panel) 82%, transparent);
|
|
color: var(--color-text-secondary);
|
|
font-size: var(--font-size-small);
|
|
}
|
|
|
|
.browser-config-warning {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 9px;
|
|
padding: 11px 12px;
|
|
border: 1px solid color-mix(in srgb, #d97706 44%, var(--color-border));
|
|
border-radius: 8px;
|
|
background: color-mix(in srgb, #d97706 14%, var(--color-background));
|
|
color: color-mix(in srgb, var(--color-text) 86%, #92400e);
|
|
font-size: var(--font-size-small);
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.browser-config-warning .material-symbols-outlined {
|
|
color: #b45309;
|
|
font-size: 20px;
|
|
}
|
|
|
|
.browser-config-sections .spinning {
|
|
display: inline-block;
|
|
transform-origin: center;
|
|
animation: browser-config-spin 0.8s linear infinite;
|
|
}
|
|
|
|
@keyframes browser-config-spin {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.browser-config-pill-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
}
|
|
|
|
.browser-config-pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
min-height: 28px;
|
|
padding: 0 10px;
|
|
border-radius: 999px;
|
|
border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
background: color-mix(in srgb, var(--color-panel) 88%, transparent);
|
|
font-size: 0.78rem;
|
|
color: var(--color-text-secondary);
|
|
}
|
|
|
|
.browser-config-pill.tone-active {
|
|
color: #1b5e20;
|
|
border-color: rgba(27, 94, 32, 0.18);
|
|
background: rgba(46, 125, 50, 0.12);
|
|
}
|
|
</style>
|
|
</body>
|
|
</html>
|