mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-08-25 00:06:30 +00:00
Use the shared toast action row and primary button classes for the Test in new chat action. Remove the plugin-specific link styling and cover the shared markup in the focused WebUI regression test.
614 lines
72 KiB
HTML
614 lines
72 KiB
HTML
<html>
|
||
<head>
|
||
<title>Agent Editor</title>
|
||
<script type="module">
|
||
import { store } from "/plugins/_agent_editor/webui/agent-editor-store.js";
|
||
</script>
|
||
</head>
|
||
<body>
|
||
<div x-data class="agent-editor" x-init="await $store.agentEditor.mount($el)"
|
||
@keydown.ctrl.s.prevent="$store.agentEditor.save(false)"
|
||
@keydown.meta.s.prevent="$store.agentEditor.save(false)">
|
||
<template x-if="$store.agentEditor.error">
|
||
<div class="agent-editor-error" role="alert">
|
||
<x-icon name="error"></x-icon>
|
||
<span x-text="$store.agentEditor.error"></span>
|
||
<button type="button" class="button icon" aria-label="Dismiss error" @click="$store.agentEditor.error = ''"><x-icon name="close"></x-icon></button>
|
||
</div>
|
||
</template>
|
||
|
||
<template x-if="$store.agentEditor.loading">
|
||
<div class="agent-editor-loading" role="status">
|
||
<x-icon class="spinning" name="progress_activity"></x-icon>
|
||
<span>Loading agent…</span>
|
||
</div>
|
||
</template>
|
||
|
||
<template x-if="!$store.agentEditor.loading && $store.agentEditor.view === 'manage'">
|
||
<section class="agent-manager" aria-label="Manage agents">
|
||
<div class="agent-scope-selector">
|
||
<label class="agent-scope-field">
|
||
<span>Project</span>
|
||
<select x-model="$store.agentEditor.projectName"
|
||
x-init="$nextTick(() => $el.value = $store.agentEditor.projectName)"
|
||
@change="$store.agentEditor.onScopeChanged()">
|
||
<option value="">Global</option>
|
||
<template x-for="project in $store.agentEditor.projects" :key="project.key">
|
||
<option :value="project.key" x-text="project.label"></option>
|
||
</template>
|
||
</select>
|
||
</label>
|
||
</div>
|
||
<div class="agent-manager-list-header">
|
||
<template x-if="$store.agentEditor.activeProfile()">
|
||
<div class="active-agent-display">
|
||
<span class="active-agent-summary">
|
||
<span>Active:</span>
|
||
<span class="active-agent-avatar" aria-hidden="true" :style="`background:${$store.agentEditor.profileVisual($store.agentEditor.activeProfile()).color}`">
|
||
<img x-show="$store.agentEditor.profileVisual($store.agentEditor.activeProfile()).url" :src="$store.agentEditor.profileVisual($store.agentEditor.activeProfile()).url" alt="">
|
||
<span x-show="!$store.agentEditor.profileVisual($store.agentEditor.activeProfile()).url" x-text="$store.agentEditor.profileVisual($store.agentEditor.activeProfile()).initials"></span>
|
||
</span>
|
||
<strong x-text="$store.agentEditor.activeProfile().title || $store.agentEditor.activeProfile().id"></strong>
|
||
</span>
|
||
<button type="button" class="button icon-button" x-show="$store.agentEditor.activeProfile().id !== 'default'" title="Edit" :aria-label="`Edit ${$store.agentEditor.activeProfile().title || $store.agentEditor.activeProfile().id}`" @click="$store.agentEditor.loadEditor($store.agentEditor.activeProfile().id, false)"><x-icon class="icon" name="edit"></x-icon></button>
|
||
</div>
|
||
</template>
|
||
<button type="button" class="button agent-manager-create" @click="$store.agentEditor.loadEditor('new-agent', true)"><x-icon class="icon" name="add"></x-icon>Create agent</button>
|
||
</div>
|
||
<div class="agent-manager-list">
|
||
<template x-for="profile in $store.agentEditor.visibleProfiles" :key="profile.id">
|
||
<article class="agent-manager-card">
|
||
<div class="agent-manager-avatar" :style="`background:${$store.agentEditor.profileVisual(profile).color}`">
|
||
<img x-show="$store.agentEditor.profileVisual(profile).url" :src="$store.agentEditor.profileVisual(profile).url" :alt="`${profile.title || profile.id} avatar`">
|
||
<span x-show="!$store.agentEditor.profileVisual(profile).url" x-text="$store.agentEditor.profileVisual(profile).initials"></span>
|
||
</div>
|
||
<div class="agent-manager-copy">
|
||
<div class="agent-manager-name">
|
||
<strong x-text="profile.title || profile.id"></strong>
|
||
<span class="agent-origin" x-text="profile.origin"></span>
|
||
</div>
|
||
<p x-text="profile.description || 'No description'"></p>
|
||
<button type="button" class="text-button agent-manager-inline-action"
|
||
:disabled="!!$store.agentEditor.duplicatingProfile"
|
||
:aria-label="`Duplicate ${profile.title || profile.id}`"
|
||
@click="$store.agentEditor.duplicateProfile(profile)">
|
||
<x-icon name="content_copy"></x-icon><span>Duplicate</span>
|
||
</button>
|
||
<button type="button" class="text-button agent-manager-inline-action"
|
||
x-show="profile.scope_has_overrides && !profile.deletable"
|
||
:disabled="$store.agentEditor.saving"
|
||
:aria-label="`Reset ${profile.title || profile.id} to default`"
|
||
@click="$store.agentEditor.restoreProfile(profile)">
|
||
<x-icon name="restore"></x-icon><span>Reset to default</span>
|
||
</button>
|
||
</div>
|
||
<div class="agent-manager-actions">
|
||
<label class="toggle agent-profile-availability"
|
||
:title="`${profile.enabled ? 'Make unavailable' : 'Make available'} in ${$store.agentEditor.scopeLabel}`">
|
||
<input type="checkbox"
|
||
:checked="profile.enabled"
|
||
:disabled="$store.agentEditor.profileAvailabilitySaving"
|
||
:aria-label="`${profile.enabled ? 'Disable' : 'Enable'} ${profile.title || profile.id} in ${$store.agentEditor.scopeLabel}`"
|
||
@change="$store.agentEditor.setProfileEnabled(profile, $event.target.checked)"
|
||
@click.stop>
|
||
<span class="toggler"></span>
|
||
</label>
|
||
<button type="button" class="button icon-button" title="Edit" :aria-label="`Edit ${profile.title || profile.id}`" @click="$store.agentEditor.loadEditor(profile.id, false)"><x-icon class="icon" name="edit"></x-icon></button>
|
||
<button type="button" class="button cancel icon-button" x-show="profile.deletable" title="Delete" :aria-label="`Delete ${profile.title || profile.id}`" @click="$store.agentEditor.deleteProfile(profile.id)"><x-icon class="icon" name="delete"></x-icon></button>
|
||
</div>
|
||
</article>
|
||
</template>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
|
||
<template x-if="!$store.agentEditor.loading && $store.agentEditor.view === 'editor' && $store.agentEditor.draft">
|
||
<div class="agent-editor-workspace">
|
||
<header class="agent-editor-topbar">
|
||
<div class="agent-editor-heading">
|
||
<button type="button" class="button icon" x-show="$store.agentEditor.intent.view === 'manage'" aria-label="Back to agents" @click="$store.agentEditor.showManager()"><x-icon name="arrow_back"></x-icon></button>
|
||
<label class="agent-scope-field agent-editor-scope">
|
||
<span>Project</span>
|
||
<select x-model="$store.agentEditor.projectName"
|
||
x-init="$nextTick(() => $el.value = $store.agentEditor.projectName)"
|
||
@change="$store.agentEditor.onScopeChanged()">
|
||
<option value="">Global</option>
|
||
<template x-for="project in $store.agentEditor.projects" :key="project.key">
|
||
<option :value="project.key" x-text="project.label"></option>
|
||
</template>
|
||
</select>
|
||
</label>
|
||
<div class="agent-editor-subtitle" x-show="$store.agentEditor.dirty">
|
||
<span class="agent-status-badge is-unsaved"><x-icon name="edit_note"></x-icon><span>Unsaved changes</span></span>
|
||
</div>
|
||
</div>
|
||
<div class="agent-editor-topbar-actions">
|
||
<div class="agent-mode-switch" role="group" aria-label="Editor mode">
|
||
<button type="button" :class="{ active: $store.agentEditor.mode === 'easy' }" :aria-pressed="$store.agentEditor.mode === 'easy'" @click="$store.agentEditor.setMode('easy')">Easy</button>
|
||
<button type="button" :class="{ active: $store.agentEditor.mode === 'advanced' }" :aria-pressed="$store.agentEditor.mode === 'advanced'" @click="$store.agentEditor.setMode('advanced')">Advanced</button>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="agent-easy" x-show="$store.agentEditor.mode === 'easy'">
|
||
<section class="agent-easy-identity">
|
||
<div class="agent-avatar-wrap">
|
||
<div class="agent-avatar" :style="`background:${$store.agentEditor.avatarColor()}`">
|
||
<img x-show="$store.agentEditor.draft.avatar?.kind === 'image' && $store.agentEditor.draft.avatarPreview" :src="$store.agentEditor.draft.avatarPreview" alt="Avatar crop preview">
|
||
<span x-show="$store.agentEditor.draft.avatar?.kind !== 'image' || !$store.agentEditor.draft.avatarPreview" x-text="$store.agentEditor.initials()"></span>
|
||
<div class="avatar-progress" x-show="$store.agentEditor.avatarUploading" aria-label="Uploading avatar"><x-icon class="spinning" name="progress_activity"></x-icon></div>
|
||
</div>
|
||
<div class="agent-avatar-actions">
|
||
<label class="avatar-action-icon avatar-color-action" title="Choose color"><x-icon name="palette"></x-icon><span class="sr-only">Choose color</span><input type="color" :value="$store.agentEditor.avatarColor()" @input="$store.agentEditor.chooseAvatarColor($event.target.value)" aria-label="Choose avatar color"></label>
|
||
<label class="avatar-action-icon avatar-upload-action" title="Upload image"><x-icon name="add_photo_alternate"></x-icon><span class="sr-only">Upload image</span><input type="file" accept="image/png,image/jpeg,image/webp" @change="$store.agentEditor.uploadAvatar($event)" aria-label="Upload avatar image"></label>
|
||
<button type="button" class="text-button" x-show="$store.agentEditor.state.profile.metadata.avatar.has_override || $store.agentEditor.draft.avatar" @click="$store.agentEditor.resetAvatar()">Reset</button>
|
||
</div>
|
||
</div>
|
||
<div class="agent-easy-identity-fields">
|
||
<div class="agent-field agent-name-field">
|
||
<label for="agent-editor-name" class="agent-field-label">Agent name</label>
|
||
<input id="agent-editor-name" type="text" x-model="$store.agentEditor.draft.title" @input="$store.agentEditor.onNameInput(); $store.agentEditor.markMetadataSet('title')" required autocomplete="off" :aria-invalid="$store.agentEditor.fieldIssue('name') ? 'true' : null" :aria-describedby="$store.agentEditor.fieldIssue('name') ? 'agent-editor-name-error' : null">
|
||
<div class="agent-id-feedback" x-show="$store.agentEditor.fieldIssue('name')">
|
||
<span id="agent-editor-name-error" class="field-error" role="alert" x-text="$store.agentEditor.fieldIssue('name')?.message"></span>
|
||
<button type="button" class="text-button" x-show="$store.agentEditor.profileConflict" @click="$store.agentEditor.openConflictingProfile()">Open existing agent</button>
|
||
</div>
|
||
</div>
|
||
<div class="agent-field agent-model-preset">
|
||
<label for="agent-editor-easy-model-preset" class="agent-field-label">Model preset</label>
|
||
<div class="agent-model-preset-picker">
|
||
<select id="agent-editor-easy-model-preset" x-model="$store.agentEditor.draft.modelPreset" x-effect="$nextTick(() => { $el.value = $store.agentEditor.draft.modelPreset })">
|
||
<option value="" x-text="`Use current preset (${$store.agentEditor.state.model_preset.effective})`"></option>
|
||
<template x-for="preset in $store.agentEditor.state.model_presets" :key="preset.name">
|
||
<option :value="preset.name" x-text="preset.name"></option>
|
||
</template>
|
||
</select>
|
||
<button type="button" class="button" @click="$store.agentEditor.openPresetManager()"><x-icon class="icon" name="tune"></x-icon>Edit Presets</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="agent-easy-field">
|
||
<div class="agent-field-heading">
|
||
<div><label for="agent-editor-instructions" class="agent-field-label">Instructions</label><p>What should this agent do, and how should it behave?</p></div>
|
||
</div>
|
||
<div>
|
||
<textarea id="agent-editor-instructions" rows="9" x-model="$store.agentEditor.instructions.value" @input="$store.agentEditor.markPromptSet('agent.system.main.specifics.md')" placeholder="Research technical topics, verify important claims with reliable sources, and return concise reports with links." :aria-invalid="$store.agentEditor.fieldIssue('instructions') ? 'true' : null" :aria-describedby="$store.agentEditor.fieldIssue('instructions') ? 'agent-editor-instructions-error' : null"></textarea>
|
||
<span id="agent-editor-instructions-error" class="field-error" role="alert" x-show="$store.agentEditor.fieldIssue('instructions')" x-text="$store.agentEditor.fieldIssue('instructions')?.message"></span>
|
||
<button type="button" class="text-button restore-action" x-show="$store.agentEditor.instructions.has_override && !$store.agentEditor.instructions.reset" @click="$store.agentEditor.restoreInstructions()"><x-icon name="restart_alt"></x-icon><span>Reset to default</span></button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="agent-easy-field agent-easy-capabilities">
|
||
<div class="agent-field-heading"><div><div class="agent-field-label">Capabilities</div><p>Choose the default access, or set individual items On or Off.</p></div></div>
|
||
<div class="capability-policy-group">
|
||
<div class="future-policy-control"><strong>Allow tools by default</strong><label class="toggle"><input type="checkbox" :checked="$store.agentEditor.policyDefault('tool') === 'allow'" @change="$store.agentEditor.setPolicyDefault('tool', $event.target.checked ? 'allow' : 'block')" aria-label="Allow tools by default"><span class="toggler"></span></label></div>
|
||
<details class="capability-accordion">
|
||
<summary><span>Choose individual tools</span><x-icon name="expand_more"></x-icon></summary>
|
||
<div class="policy-items" role="list" aria-label="Tools this agent can use">
|
||
<template x-for="tool in $store.agentEditor.standardToolCatalog" :key="tool.id">
|
||
<div class="policy-item" role="listitem"><div class="policy-item-copy"><strong x-text="tool.label"></strong><p class="policy-item-description" x-show="tool.description" x-text="tool.description"></p></div><div class="policy-state-control" role="group" :aria-label="`${tool.label} access`"><button type="button" :class="{ active: $store.agentEditor.policyItemState('tool', tool.id) === 'allow' }" :aria-pressed="$store.agentEditor.policyItemState('tool', tool.id) === 'allow'" @click="$store.agentEditor.setPolicyItem('tool', tool.id, 'allow')">On</button><button type="button" :class="{ active: $store.agentEditor.policyItemState('tool', tool.id) === 'default' }" :aria-pressed="$store.agentEditor.policyItemState('tool', tool.id) === 'default'" @click="$store.agentEditor.setPolicyItem('tool', tool.id, 'default')" x-text="`Default (${$store.agentEditor.policyDefault('tool') === 'allow' ? 'on' : 'off'})`"></button><button type="button" :class="{ active: $store.agentEditor.policyItemState('tool', tool.id) === 'block' }" :aria-pressed="$store.agentEditor.policyItemState('tool', tool.id) === 'block'" @click="$store.agentEditor.setPolicyItem('tool', tool.id, 'block')">Off</button></div></div>
|
||
</template>
|
||
<p class="policy-empty" x-show="!$store.agentEditor.standardToolCatalog.length">No configurable tools are available.</p>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
|
||
<div class="capability-policy-group">
|
||
<div class="future-policy-control"><strong>Allow MCPs by default</strong><label class="toggle"><input type="checkbox" :checked="$store.agentEditor.policyDefault('mcp') === 'allow'" @change="$store.agentEditor.setPolicyDefault('mcp', $event.target.checked ? 'allow' : 'block')" aria-label="Allow MCPs by default"><span class="toggler"></span></label></div>
|
||
<details class="capability-accordion">
|
||
<summary><span>Choose individual MCPs</span><x-icon name="expand_more"></x-icon></summary>
|
||
<div class="policy-items" role="list" aria-label="MCP tools this agent can use">
|
||
<template x-for="tool in $store.agentEditor.mcpCatalog" :key="tool.id">
|
||
<div class="policy-item" role="listitem"><div class="policy-item-copy"><strong x-text="tool.label"></strong><p class="policy-item-description" x-show="tool.description" x-text="tool.description"></p></div><div class="policy-state-control" role="group" :aria-label="`${tool.label} access`"><button type="button" :class="{ active: $store.agentEditor.policyItemState('mcp', tool.id) === 'allow' }" :aria-pressed="$store.agentEditor.policyItemState('mcp', tool.id) === 'allow'" @click="$store.agentEditor.setPolicyItem('mcp', tool.id, 'allow')">On</button><button type="button" :class="{ active: $store.agentEditor.policyItemState('mcp', tool.id) === 'default' }" :aria-pressed="$store.agentEditor.policyItemState('mcp', tool.id) === 'default'" @click="$store.agentEditor.setPolicyItem('mcp', tool.id, 'default')" x-text="`Default (${$store.agentEditor.policyDefault('mcp') === 'allow' ? 'on' : 'off'})`"></button><button type="button" :class="{ active: $store.agentEditor.policyItemState('mcp', tool.id) === 'block' }" :aria-pressed="$store.agentEditor.policyItemState('mcp', tool.id) === 'block'" @click="$store.agentEditor.setPolicyItem('mcp', tool.id, 'block')">Off</button></div></div>
|
||
</template>
|
||
<p class="policy-empty" x-show="!$store.agentEditor.mcpCatalog.length">No MCP tools are available.</p>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
|
||
<div class="capability-policy-group">
|
||
<div class="future-policy-control"><strong>Allow skills by default</strong><label class="toggle"><input type="checkbox" :checked="$store.agentEditor.policyDefault('skill') === 'allow'" @change="$store.agentEditor.setPolicyDefault('skill', $event.target.checked ? 'allow' : 'block')" aria-label="Allow skills by default"><span class="toggler"></span></label></div>
|
||
<details class="capability-accordion">
|
||
<summary><span>Choose individual skills</span><x-icon name="expand_more"></x-icon></summary>
|
||
<div class="policy-items" role="list" aria-label="Skills this agent can use">
|
||
<template x-for="skill in $store.agentEditor.skillCatalog" :key="skill.path">
|
||
<div class="policy-item" role="listitem"><div class="policy-item-copy"><strong x-text="skill.name"></strong><p class="policy-item-description" x-show="skill.description" x-text="skill.description"></p><em x-show="$store.agentEditor.skillWarnings(skill).length" x-text="`Expects blocked tool: ${$store.agentEditor.skillWarnings(skill).join(', ')}`"></em></div><div class="policy-state-control" role="group" :aria-label="`${skill.name} access`"><button type="button" :class="{ active: $store.agentEditor.policyItemState('skill', skill.name) === 'allow' }" :aria-pressed="$store.agentEditor.policyItemState('skill', skill.name) === 'allow'" @click="$store.agentEditor.setPolicyItem('skill', skill.name, 'allow')">On</button><button type="button" :class="{ active: $store.agentEditor.policyItemState('skill', skill.name) === 'default' }" :aria-pressed="$store.agentEditor.policyItemState('skill', skill.name) === 'default'" @click="$store.agentEditor.setPolicyItem('skill', skill.name, 'default')" x-text="`Default (${$store.agentEditor.policyDefault('skill') === 'allow' ? 'on' : 'off'})`"></button><button type="button" :class="{ active: $store.agentEditor.policyItemState('skill', skill.name) === 'block' }" :aria-pressed="$store.agentEditor.policyItemState('skill', skill.name) === 'block'" @click="$store.agentEditor.setPolicyItem('skill', skill.name, 'block')">Off</button></div></div>
|
||
</template>
|
||
<p class="policy-empty" x-show="!$store.agentEditor.skillCatalog.length">No configurable skills are available.</p>
|
||
</div>
|
||
</details>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<div class="agent-advanced" x-show="$store.agentEditor.mode === 'advanced'">
|
||
<nav class="agent-advanced-nav" aria-label="Advanced editor sections">
|
||
<template x-for="item in [{id:'1',label:'Identity'},{id:'2',label:'Prompt files'},{id:'3',label:'Tools'},{id:'4',label:'MCPs'},{id:'5',label:'Skills'},{id:'6',label:'Review'}]" :key="item.id">
|
||
<button type="button" :class="{ active: $store.agentEditor.section === item.id }" :aria-current="$store.agentEditor.section === item.id ? 'step' : null" @click="$store.agentEditor.setSection(item.id)">
|
||
<span class="section-number" x-text="item.id"></span><span x-text="item.label"></span>
|
||
<span class="agent-status-badge compact" :class="$store.agentEditor.sectionIssues(item.id).length ? 'is-error' : 'is-unsaved'" x-show="$store.agentEditor.sectionIssues(item.id).length || $store.agentEditor.sectionDirty(item.id)"><x-icon :name="$store.agentEditor.sectionIssues(item.id).length ? 'error' : 'edit_note'"></x-icon><span x-text="$store.agentEditor.sectionIssues(item.id).length ? 'Needs attention' : 'Changed'"></span></span>
|
||
</button>
|
||
</template>
|
||
</nav>
|
||
|
||
<div class="agent-advanced-content">
|
||
<section x-show="$store.agentEditor.section === '1'" data-agent-editor-section="1" tabindex="-1" aria-labelledby="agent-section-1-title">
|
||
<header class="advanced-section-heading"><h3 id="agent-section-1-title">Identity</h3><p>Set the agent’s identity, delegation guidance, and model preset.</p></header>
|
||
<div class="origin-row">
|
||
<span class="agent-origin" x-text="$store.agentEditor.state.profile.origin"></span>
|
||
<span class="agent-status-badge is-customized" x-show="$store.agentEditor.state.profile.scope_has_overrides"><x-icon name="edit_note"></x-icon><span>Customized by you</span></span>
|
||
</div>
|
||
<p class="built-in-note" x-show="$store.agentEditor.state.profile.built_in">Your changes override the built-in profile. The original files stay unchanged.</p>
|
||
<div class="advanced-identity-grid">
|
||
<div class="agent-avatar-wrap advanced-avatar">
|
||
<div class="agent-avatar" :style="`background:${$store.agentEditor.avatarColor()}`">
|
||
<img x-show="$store.agentEditor.draft.avatar?.kind === 'image' && $store.agentEditor.draft.avatarPreview" :src="$store.agentEditor.draft.avatarPreview" alt="Avatar crop preview">
|
||
<span x-show="$store.agentEditor.draft.avatar?.kind !== 'image' || !$store.agentEditor.draft.avatarPreview" x-text="$store.agentEditor.initials()"></span>
|
||
</div>
|
||
<div class="agent-avatar-actions">
|
||
<label class="avatar-action-icon avatar-color-action" title="Choose color"><x-icon name="palette"></x-icon><span class="sr-only">Choose color</span><input type="color" :value="$store.agentEditor.avatarColor()" @input="$store.agentEditor.chooseAvatarColor($event.target.value)" aria-label="Choose avatar color"></label>
|
||
<label class="avatar-action-icon avatar-upload-action" title="Upload image"><x-icon name="add_photo_alternate"></x-icon><span class="sr-only">Upload image</span><input type="file" accept="image/png,image/jpeg,image/webp" @change="$store.agentEditor.uploadAvatar($event)" aria-label="Upload avatar image"></label>
|
||
<button type="button" class="text-button" x-show="$store.agentEditor.state.profile.metadata.avatar.has_override || $store.agentEditor.draft.avatar" @click="$store.agentEditor.resetAvatar()">Reset</button>
|
||
</div>
|
||
</div>
|
||
<div class="identity-fields">
|
||
<div class="agent-field"><label for="agent-editor-advanced-name" class="agent-field-label">Agent name</label><input id="agent-editor-advanced-name" type="text" x-model="$store.agentEditor.draft.title" @input="$store.agentEditor.onNameInput(); $store.agentEditor.markMetadataSet('title')" :aria-invalid="$store.agentEditor.fieldIssue('name') ? 'true' : null" :aria-describedby="$store.agentEditor.fieldIssue('name') ? 'agent-editor-advanced-name-error' : null"><span id="agent-editor-advanced-name-error" class="field-error" role="alert" x-show="$store.agentEditor.fieldIssue('name')" x-text="$store.agentEditor.fieldIssue('name')?.message"></span><small class="field-provenance" x-show="$store.agentEditor.metadataProvenance('title')" x-text="$store.agentEditor.metadataProvenance('title')"></small><button type="button" class="text-button" x-show="$store.agentEditor.canResetMetadata('title')" @click="$store.agentEditor.resetMetadata('title')">Reset to default</button><small class="field-status" x-show="$store.agentEditor.metadataResetPending('title')">Will reset to default on save.</small></div>
|
||
<label class="agent-field"><span class="agent-field-label">Profile ID</span><input type="text" :value="$store.agentEditor.draft.profileId" readonly aria-describedby="profile-id-help"><small id="profile-id-help">Used as the profile folder name. Existing IDs do not change when the display name changes.</small></label>
|
||
<div class="agent-field wide"><label for="agent-editor-description" class="agent-field-label">Description</label><textarea id="agent-editor-description" rows="2" x-model="$store.agentEditor.draft.description" @input="$store.agentEditor.markMetadataSet('description')"></textarea><small>Short summary shown in profile lists.</small><button type="button" class="text-button" x-show="$store.agentEditor.canResetMetadata('description')" @click="$store.agentEditor.resetMetadata('description')">Reset to default</button><small class="field-status" x-show="$store.agentEditor.metadataResetPending('description')">Will reset to default on save.</small></div>
|
||
<div class="agent-field wide agent-model-preset">
|
||
<label for="agent-editor-model-preset" class="agent-field-label">Model preset</label>
|
||
<div class="agent-model-preset-picker">
|
||
<select id="agent-editor-model-preset" x-model="$store.agentEditor.draft.modelPreset" x-effect="$nextTick(() => { $el.value = $store.agentEditor.draft.modelPreset })">
|
||
<option value="" x-text="`Use current preset (${$store.agentEditor.state.model_preset.effective})`"></option>
|
||
<template x-for="preset in $store.agentEditor.state.model_presets" :key="preset.name">
|
||
<option :value="preset.name" x-text="preset.name"></option>
|
||
</template>
|
||
</select>
|
||
<button type="button" class="button" @click="$store.agentEditor.openPresetManager()"><x-icon class="icon" name="tune"></x-icon>Edit Presets</button>
|
||
</div>
|
||
<small>Use the current preset or choose another setup for this agent.</small>
|
||
</div>
|
||
<div class="agent-field wide"><label for="agent-editor-context" class="agent-field-label">When should other agents use this agent?</label><textarea id="agent-editor-context" rows="3" x-model="$store.agentEditor.draft.context" @input="$store.agentEditor.markMetadataSet('context')"></textarea><small>Helps Agent Zero decide when to delegate work; leaving this empty may reduce delegation quality.</small><button type="button" class="text-button" x-show="$store.agentEditor.canResetMetadata('context')" @click="$store.agentEditor.resetMetadata('context')">Reset to default</button><small class="field-status" x-show="$store.agentEditor.metadataResetPending('context')">Will reset to default on save.</small></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section x-show="$store.agentEditor.section === '2'" data-agent-editor-section="2" tabindex="-1" aria-labelledby="agent-section-2-title">
|
||
<header class="advanced-section-heading"><h3 id="agent-section-2-title">Prompt files</h3><p>Choose a file and edit its prompt.</p></header>
|
||
<div class="prompt-workspace">
|
||
<aside class="prompt-browser">
|
||
<label class="compact-search"><span class="sr-only">Search prompt files</span><x-icon name="search"></x-icon><input type="search" x-model="$store.agentEditor.promptFileSearch" placeholder="Search files"></label>
|
||
<div class="prompt-file-list" role="region" aria-label="Prompt file list" tabindex="0">
|
||
<template x-for="group in $store.agentEditor.promptGroups" :key="group.id">
|
||
<section class="prompt-file-group" x-show="$store.agentEditor.filteredPromptFiles(group.id).length">
|
||
<h4 x-text="group.label"></h4>
|
||
<template x-for="prompt in $store.agentEditor.filteredPromptFiles(group.id)" :key="prompt.filename">
|
||
<button type="button" :class="{ active: $store.agentEditor.selectedPrompt === prompt.filename }" @click="$store.agentEditor.selectPrompt(prompt.filename)">
|
||
<span class="prompt-file-name" x-text="prompt.filename"></span><span class="prompt-file-state" x-text="$store.agentEditor.promptDisplayState(prompt)"></span>
|
||
</button>
|
||
</template>
|
||
</section>
|
||
</template>
|
||
<p class="prompt-empty" x-show="!$store.agentEditor.filteredPromptFiles().length">No prompt files match your search.</p>
|
||
</div>
|
||
</aside>
|
||
<div class="prompt-editor" role="region" aria-label="Selected prompt file" tabindex="0" x-show="$store.agentEditor.selectedPromptDraft">
|
||
<div class="prompt-editor-header">
|
||
<div class="prompt-file-heading">
|
||
<strong x-text="$store.agentEditor.selectedPrompt"></strong>
|
||
<div class="prompt-customization-path"><code x-text="$store.agentEditor.promptCustomizationPath()"></code><button type="button" class="button" title="Copy customization path" aria-label="Copy customization path" @click="$store.agentEditor.copyPromptPath()"><x-icon name="content_copy"></x-icon></button></div>
|
||
</div>
|
||
<div class="prompt-actions">
|
||
<button type="button" class="btn btn-action-header cancel" x-show="$store.agentEditor.promptEditPending($store.agentEditor.selectedPromptDraft)" title="Discard current edit" aria-label="Discard current edit" @click="$store.agentEditor.discardPromptEdit($store.agentEditor.selectedPrompt)"><x-icon name="close"></x-icon></button>
|
||
<button type="button" class="btn btn-action-header confirm" x-show="$store.agentEditor.promptEditPending($store.agentEditor.selectedPromptDraft)" title="Accept current edit" aria-label="Accept current edit" @click="$store.agentEditor.acceptPromptEdit($store.agentEditor.selectedPrompt)"><x-icon name="check"></x-icon></button>
|
||
<button type="button" class="button" x-show="$store.agentEditor.selectedPromptDraft.has_override || $store.agentEditor.promptDirty($store.agentEditor.selectedPromptDraft)" @click="$store.agentEditor.resetPrompt($store.agentEditor.selectedPrompt)">Reset to default</button>
|
||
</div>
|
||
</div>
|
||
<div class="agent-editor-note" x-show="$store.agentEditor.selectedPromptDraft.dynamic_processor">This file is generated dynamically at runtime. Python processors are read-only and are not executed by the editor.</div>
|
||
<div id="agent-editor-prompt-ace" class="prompt-ace" :aria-invalid="$store.agentEditor.selectedPrompt === 'agent.system.main.specifics.md' && $store.agentEditor.fieldIssue('instructions') ? 'true' : null" :aria-describedby="$store.agentEditor.selectedPrompt === 'agent.system.main.specifics.md' && $store.agentEditor.fieldIssue('instructions') ? 'agent-editor-prompt-error' : null"></div>
|
||
<div class="agent-editor-note" role="alert" x-show="$store.agentEditor.aceUnavailable">Prompt editor is unavailable. Reload Agent Zero and try again.</div>
|
||
<span id="agent-editor-prompt-error" class="field-error" role="alert" x-show="$store.agentEditor.selectedPrompt === 'agent.system.main.specifics.md' && $store.agentEditor.fieldIssue('instructions')" x-text="$store.agentEditor.fieldIssue('instructions')?.message"></span>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section x-show="$store.agentEditor.section === '3'" data-agent-editor-section="3" tabindex="-1" aria-labelledby="agent-section-3-title">
|
||
<header class="advanced-section-heading"><h3 id="agent-section-3-title">Tools</h3><p>Choose which tools this agent can use.</p></header>
|
||
<div class="future-policy-control"><strong>Allow tools by default</strong><label class="toggle"><input type="checkbox" :checked="$store.agentEditor.policyDefault('tool') === 'allow'" @change="$store.agentEditor.setPolicyDefault('tool', $event.target.checked ? 'allow' : 'block')" aria-label="Allow tools by default"><span class="toggler"></span></label></div>
|
||
<div class="policy-filters tools"><label class="policy-search"><x-icon name="search"></x-icon><span class="sr-only">Search tools</span><input type="search" x-model="$store.agentEditor.toolSearch" placeholder="Search tools"></label><label>Origin <select x-model="$store.agentEditor.toolOrigin"><option value="all">All</option><template x-for="origin in $store.agentEditor.toolOrigins" :key="origin"><option :value="origin" x-text="origin"></option></template></select></label></div>
|
||
<section class="policy-group" aria-labelledby="tools-title"><header><h4 id="tools-title">Tools</h4><span x-text="$store.agentEditor.filteredTools('tool').length"></span></header><div class="policy-items"><p class="policy-empty" x-show="!$store.agentEditor.filteredTools('tool').length">No tools match these filters.</p><template x-for="tool in $store.agentEditor.filteredTools('tool')" :key="tool.id"><div class="policy-item"><div class="policy-item-copy"><strong x-text="tool.label"></strong><small x-text="tool.id"></small><p class="policy-item-description" x-show="tool.description" x-text="tool.description"></p><em x-show="tool.available === false">Unavailable — kept in your settings</em></div><div class="policy-state-control" role="group" :aria-label="`${tool.label} access`"><button type="button" :class="{ active: $store.agentEditor.policyItemState('tool', tool.id) === 'allow' }" :aria-pressed="$store.agentEditor.policyItemState('tool', tool.id) === 'allow'" @click="$store.agentEditor.setPolicyItem('tool', tool.id, 'allow')">On</button><button type="button" :class="{ active: $store.agentEditor.policyItemState('tool', tool.id) === 'default' }" :aria-pressed="$store.agentEditor.policyItemState('tool', tool.id) === 'default'" @click="$store.agentEditor.setPolicyItem('tool', tool.id, 'default')" x-text="`Default (${$store.agentEditor.policyDefault('tool') === 'allow' ? 'on' : 'off'})`"></button><button type="button" :class="{ active: $store.agentEditor.policyItemState('tool', tool.id) === 'block' }" :aria-pressed="$store.agentEditor.policyItemState('tool', tool.id) === 'block'" @click="$store.agentEditor.setPolicyItem('tool', tool.id, 'block')">Off</button></div></div></template></div></section>
|
||
</section>
|
||
|
||
<section x-show="$store.agentEditor.section === '4'" data-agent-editor-section="4" tabindex="-1" aria-labelledby="agent-section-4-title">
|
||
<header class="advanced-section-heading"><h3 id="agent-section-4-title">MCPs</h3><p>Choose which MCP tools this agent can use.</p></header>
|
||
<div class="future-policy-control"><strong>Allow MCPs by default</strong><label class="toggle"><input type="checkbox" :checked="$store.agentEditor.policyDefault('mcp') === 'allow'" @change="$store.agentEditor.setPolicyDefault('mcp', $event.target.checked ? 'allow' : 'block')" aria-label="Allow MCPs by default"><span class="toggler"></span></label></div>
|
||
<div class="policy-filters tools"><label class="policy-search"><x-icon name="search"></x-icon><span class="sr-only">Search MCPs</span><input type="search" x-model="$store.agentEditor.toolSearch" placeholder="Search MCPs"></label><label>Origin <select x-model="$store.agentEditor.toolOrigin"><option value="all">All</option><template x-for="origin in $store.agentEditor.toolOrigins" :key="origin"><option :value="origin" x-text="origin"></option></template></select></label></div>
|
||
<section class="policy-group" aria-labelledby="mcps-title"><header><h4 id="mcps-title">MCPs</h4><span x-text="$store.agentEditor.filteredTools('mcp').length"></span></header><div class="policy-items"><p class="policy-empty" x-show="!$store.agentEditor.filteredTools('mcp').length">No MCP tools match these filters.</p><template x-for="tool in $store.agentEditor.filteredTools('mcp')" :key="tool.id"><div class="policy-item"><div class="policy-item-copy"><strong x-text="tool.label"></strong><small x-text="tool.id"></small><p class="policy-item-description" x-show="tool.description" x-text="tool.description"></p><em x-show="tool.available === false">Unavailable — kept in your settings</em></div><div class="policy-state-control" role="group" :aria-label="`${tool.label} access`"><button type="button" :class="{ active: $store.agentEditor.policyItemState('mcp', tool.id) === 'allow' }" :aria-pressed="$store.agentEditor.policyItemState('mcp', tool.id) === 'allow'" @click="$store.agentEditor.setPolicyItem('mcp', tool.id, 'allow')">On</button><button type="button" :class="{ active: $store.agentEditor.policyItemState('mcp', tool.id) === 'default' }" :aria-pressed="$store.agentEditor.policyItemState('mcp', tool.id) === 'default'" @click="$store.agentEditor.setPolicyItem('mcp', tool.id, 'default')" x-text="`Default (${$store.agentEditor.policyDefault('mcp') === 'allow' ? 'on' : 'off'})`"></button><button type="button" :class="{ active: $store.agentEditor.policyItemState('mcp', tool.id) === 'block' }" :aria-pressed="$store.agentEditor.policyItemState('mcp', tool.id) === 'block'" @click="$store.agentEditor.setPolicyItem('mcp', tool.id, 'block')">Off</button></div></div></template></div></section>
|
||
</section>
|
||
|
||
<section x-show="$store.agentEditor.section === '5'" data-agent-editor-section="5" tabindex="-1" aria-labelledby="agent-section-5-title">
|
||
<header class="advanced-section-heading"><h3 id="agent-section-5-title">Skills</h3><p>Choose which skills this agent can find and use.</p></header>
|
||
<div class="future-policy-control"><strong>Allow skills by default</strong><label class="toggle"><input type="checkbox" :checked="$store.agentEditor.policyDefault('skill') === 'allow'" @change="$store.agentEditor.setPolicyDefault('skill', $event.target.checked ? 'allow' : 'block')" aria-label="Allow skills by default"><span class="toggler"></span></label></div>
|
||
<div class="policy-filters skills"><label class="policy-search"><x-icon name="search"></x-icon><span class="sr-only">Search skills</span><input type="search" x-model="$store.agentEditor.skillSearch" placeholder="Search skills"></label><label>Origin <select x-model="$store.agentEditor.skillOrigin"><option value="all">All</option><template x-for="origin in $store.agentEditor.skillOrigins" :key="origin"><option :value="origin" x-text="origin"></option></template></select></label></div>
|
||
<section class="policy-group" aria-labelledby="skills-title"><header><h4 id="skills-title">Skills</h4><span x-text="$store.agentEditor.filteredSkills().length"></span></header><div class="policy-items"><p class="policy-empty" x-show="!$store.agentEditor.filteredSkills().length">No skills match these filters.</p><template x-for="skill in $store.agentEditor.filteredSkills()" :key="skill.path"><div class="policy-item"><div class="policy-item-copy"><strong x-text="skill.name"></strong><small x-text="skill.origin"></small><p class="policy-item-description" x-show="skill.description" x-text="skill.description"></p><em x-show="skill.available === false">Unavailable — kept in your settings</em><em x-show="$store.agentEditor.skillWarnings(skill).length" x-text="`Expects blocked tool: ${$store.agentEditor.skillWarnings(skill).join(', ')}`"></em></div><div class="policy-state-control" role="group" :aria-label="`${skill.name} access`"><button type="button" :class="{ active: $store.agentEditor.policyItemState('skill', skill.name) === 'allow' }" :aria-pressed="$store.agentEditor.policyItemState('skill', skill.name) === 'allow'" @click="$store.agentEditor.setPolicyItem('skill', skill.name, 'allow')">On</button><button type="button" :class="{ active: $store.agentEditor.policyItemState('skill', skill.name) === 'default' }" :aria-pressed="$store.agentEditor.policyItemState('skill', skill.name) === 'default'" @click="$store.agentEditor.setPolicyItem('skill', skill.name, 'default')" x-text="`Default (${$store.agentEditor.policyDefault('skill') === 'allow' ? 'on' : 'off'})`"></button><button type="button" :class="{ active: $store.agentEditor.policyItemState('skill', skill.name) === 'block' }" :aria-pressed="$store.agentEditor.policyItemState('skill', skill.name) === 'block'" @click="$store.agentEditor.setPolicyItem('skill', skill.name, 'block')">Off</button></div></div></template></div></section>
|
||
</section>
|
||
|
||
<section x-show="$store.agentEditor.section === '6'" data-agent-editor-section="6" tabindex="-1" aria-labelledby="agent-section-6-title">
|
||
<header class="advanced-section-heading"><h3 id="agent-section-6-title">Review</h3><p>Saving will change exactly these files — nothing else.</p></header>
|
||
<div class="review-plan-status" role="status" x-show="$store.agentEditor.planStatus === 'loading'"><x-icon class="spinning" name="progress_activity"></x-icon><span>Computing the exact change plan…</span></div>
|
||
<div class="review-plan-status" x-show="$store.agentEditor.planStatus === 'error'"><span>The change plan could not be computed.</span><button type="button" class="text-button" @click="$store.agentEditor.previewPlan()">Retry</button></div>
|
||
<div class="review-blocked" role="alert" x-show="$store.agentEditor.planStatus === 'blocked'">
|
||
<x-icon name="error"></x-icon>
|
||
<div><strong x-text="`Fix ${$store.agentEditor.validationIssues().length} ${$store.agentEditor.validationIssues().length === 1 ? 'issue' : 'issues'} to see the change plan`"></strong>
|
||
<ul><template x-for="issue in $store.agentEditor.validationIssues()" :key="`${issue.section}-${issue.field}-${issue.message}`"><li><button type="button" class="text-button" @click="$store.agentEditor.showValidationIssue(issue)" x-text="`${issue.label}: ${issue.message} — fix`"></button></li></template></ul>
|
||
</div>
|
||
</div>
|
||
<section class="review-identity" aria-label="Agent identity" x-show="$store.agentEditor.planStatus === 'ready'">
|
||
<div class="review-identity-avatar" aria-hidden="true" :style="`background:${$store.agentEditor.avatarColor()}`"><img x-show="$store.agentEditor.draft.avatar?.kind === 'image' && $store.agentEditor.draft.avatarPreview" :src="$store.agentEditor.draft.avatarPreview" alt=""><span x-show="$store.agentEditor.draft.avatar?.kind !== 'image' || !$store.agentEditor.draft.avatarPreview" x-text="$store.agentEditor.initials()"></span></div>
|
||
<div><strong x-text="$store.agentEditor.draft.title || $store.agentEditor.draft.profileId"></strong><p x-text="$store.agentEditor.draft.description || 'No description'"></p></div>
|
||
</section>
|
||
<div class="change-plan" aria-live="polite" x-show="$store.agentEditor.planStatus === 'ready'">
|
||
<section><h4>Will create or update</h4><template x-if="!$store.agentEditor.plan.written?.length"><p>None</p></template><ul><template x-for="path in $store.agentEditor.plan.written || []" :key="path"><li><code x-text="path"></code></li></template></ul></section>
|
||
<section><h4>Will delete</h4><template x-if="!$store.agentEditor.plan.deleted?.length"><p>None</p></template><ul><template x-for="path in $store.agentEditor.plan.deleted || []" :key="path"><li><code x-text="path"></code></li></template></ul></section>
|
||
<template x-if="$store.agentEditor.plan.warnings?.length"><section><h4>Notices</h4><ul><template x-for="warning in $store.agentEditor.plan.warnings" :key="warning"><li x-text="warning"></li></template></ul></section></template>
|
||
</div>
|
||
<div class="review-actions" x-show="$store.agentEditor.pendingMutation"><button type="button" class="button danger" @click="$store.agentEditor.applyPendingMutation()"><x-icon name="delete"></x-icon>Apply removal plan</button><button type="button" class="text-button" @click="$store.agentEditor.pendingMutation = null; $store.agentEditor.previewPlan()">Cancel removal</button></div>
|
||
<div class="profile-maintenance" x-show="!$store.agentEditor.pendingMutation && !$store.agentEditor.draft.creating && $store.agentEditor.state.profile.scope_has_overrides && !$store.agentEditor.state.profile.deletable">
|
||
<h4>Customized by you</h4><p x-text="`Remove only the customizations shown in this editor from ${$store.agentEditor.scopeLabel}. Other files stay in place.`"></p><button type="button" class="button danger" @click="$store.agentEditor.planRemoval(false)"><x-icon name="delete_sweep"></x-icon>Remove my changes</button>
|
||
<details><summary x-text="`Delete all customizations in ${$store.agentEditor.scopeLabel}`"></summary><p>This removes every customization saved in this scope after showing each affected file. Inherited files remain untouched.</p><button type="button" class="button danger" @click="$store.agentEditor.planRemoval(true)"><x-icon name="delete_forever"></x-icon>Review files to delete</button></details>
|
||
</div>
|
||
<div class="profile-maintenance" x-show="!$store.agentEditor.pendingMutation && !$store.agentEditor.draft.creating && $store.agentEditor.state.profile.deletable"><h4>Delete custom agent</h4><p>Projects and open chats that use this agent are shown before confirmation, together with its files and settings.</p><button type="button" class="button danger" @click="$store.agentEditor.deleteProfile($store.agentEditor.draft.profileId)">Delete agent</button></div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</template>
|
||
|
||
<div class="modal-footer agent-editor-footer" data-modal-footer x-show="!$store.agentEditor.loading && $store.agentEditor.view === 'editor' && !$store.agentEditor.pendingMutation">
|
||
<div class="footer-left">
|
||
<button type="button" class="btn btn-cancel agent-reset-profile"
|
||
x-show="$store.agentEditor.draft && !$store.agentEditor.draft.creating && $store.agentEditor.state?.profile && !$store.agentEditor.state.profile.deletable"
|
||
:disabled="$store.agentEditor.saving || !$store.agentEditor.state?.profile?.scope_has_overrides"
|
||
@click="$store.agentEditor.restoreProfile($store.agentEditor.state.profile)">Reset to default</button>
|
||
</div>
|
||
<div class="footer-actions">
|
||
<button type="button" class="btn agent-editor-secondary-action" x-show="$store.agentEditor.view === 'editor' && !$store.agentEditor.draft?.creating" @click="$store.agentEditor.save(true)" :disabled="$store.agentEditor.saving || $store.agentEditor.validationIssues().length > 0">Save & test</button>
|
||
<button type="button" class="btn btn-ok" x-show="$store.agentEditor.view === 'editor'" @click="$store.agentEditor.save(false)" :disabled="$store.agentEditor.saving || $store.agentEditor.avatarUploading || $store.agentEditor.validationIssues().length > 0" :title="$store.agentEditor.validationIssues().length ? 'Fix the highlighted issues before saving' : ''"><span x-text="$store.agentEditor.saving ? 'Saving…' : $store.agentEditor.draft?.creating ? 'Create agent' : 'Save changes'"></span></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
.agent-editor {
|
||
--color-text-secondary: var(--color-text-muted);
|
||
--color-error: var(--color-error-text);
|
||
--color-warning: var(--color-warning-text);
|
||
--agent-editor-action: var(--color-highlight);
|
||
--agent-editor-change: var(--color-warning-text);
|
||
--agent-editor-danger: var(--color-error-text);
|
||
color: var(--color-text);
|
||
min-height: 12rem;
|
||
min-width: 0;
|
||
}
|
||
.agent-editor h2,.agent-editor h3,.agent-editor h4,.agent-editor p { margin: 0; }
|
||
.agent-editor button,.agent-editor input,.agent-editor textarea,.agent-editor select { font: inherit; }
|
||
.agent-editor input[type="search"],.agent-editor select { min-width:0; min-height:2.25rem; box-sizing:border-box; padding:.5rem .6rem; border:1px solid var(--color-border); border-radius:7px; background:var(--color-input); color:var(--color-text); }
|
||
.agent-editor input[type="radio"] { appearance:none; flex:0 0 auto; width:1.5rem; height:1.5rem; margin:.05rem 0; border:1px solid var(--color-border); background:var(--color-input); }
|
||
.agent-editor input[type="radio"] { border-radius:50%; }
|
||
.agent-editor input[type="radio"]:checked { border-color:var(--agent-editor-action); box-shadow:inset 0 0 0 4px var(--color-input); background:var(--agent-editor-action); }
|
||
.agent-editor-error { display:flex; gap:.55rem; align-items:flex-start; margin:0 0 .8rem; padding:.7rem .8rem; border:1px solid color-mix(in srgb,var(--agent-editor-danger) 55%,var(--color-border)); border-radius:8px; background:color-mix(in srgb,var(--agent-editor-danger) 10%,var(--color-panel)); }
|
||
.agent-editor-error span { flex:1; white-space:pre-wrap; }
|
||
.agent-editor-loading { min-height:20rem; display:grid; place-content:center; justify-items:center; gap:.65rem; color:var(--color-text-secondary); }
|
||
.agent-editor-topbar { display:flex; align-items:center; justify-content:space-between; gap:1rem; margin-bottom:1rem; }
|
||
.agent-editor-heading { display:flex; flex:1 1 auto; flex-wrap:wrap; align-items:center; gap:.6rem; min-width:0; }
|
||
.agent-editor-subtitle { margin-top:.2rem; font-size:.78rem; color:var(--color-text-secondary); }
|
||
.agent-editor-topbar-actions { display:flex; align-items:center; gap:.75rem; margin-left:auto; }
|
||
.agent-editor .agent-reset-profile { --agent-editor-action:var(--color-primary); gap:.25rem; white-space:nowrap; }
|
||
.agent-status-badge { display:inline-flex; align-items:center; gap:.25rem; max-width:100%; padding:.2rem .45rem; border:1px solid var(--color-border); border-radius:999px; font-size:.7rem; font-weight:500; line-height:1.2; white-space:normal; }
|
||
.agent-status-badge x-icon { flex:0 0 auto; font-size:.85rem; }
|
||
.agent-status-badge.is-customized,.agent-status-badge.is-unsaved { color:var(--agent-editor-change); border-color:color-mix(in srgb,var(--agent-editor-change) 44%,var(--color-border)); background:color-mix(in srgb,var(--agent-editor-change) 8%,transparent); }
|
||
.agent-status-badge.is-error { color:var(--agent-editor-danger); border-color:color-mix(in srgb,var(--agent-editor-danger) 48%,var(--color-border)); background:color-mix(in srgb,var(--agent-editor-danger) 8%,transparent); }
|
||
.agent-status-badge.compact { justify-self:end; padding:.15rem .35rem; font-size:.64rem; }
|
||
.agent-mode-switch { display:flex; margin-left:auto; padding:3px; border:1px solid var(--color-border); border-radius:9px; background:var(--color-input); }
|
||
.agent-mode-switch button { border:0; border-radius:6px; padding:.42rem .8rem; color:var(--color-text-secondary); background:transparent; }
|
||
.agent-mode-switch button.active { color:var(--color-text); background:var(--color-panel); box-shadow:0 1px 4px rgba(0,0,0,.2); }
|
||
.agent-easy { max-width:43rem; margin:0 auto; display:flex; flex-direction:column; gap:1.35rem; padding:.25rem .25rem 1rem; }
|
||
.agent-easy-identity { position:relative; display:grid; grid-template-columns:7.2rem 1fr; gap:1rem; align-items:start; }
|
||
.agent-easy-identity-fields { width:100%; min-width:0; display:flex; flex-direction:column; gap:.9rem; }
|
||
.agent-avatar-wrap { display:flex; flex-direction:column; align-items:center; gap:.45rem; }
|
||
.agent-avatar { width:5rem; aspect-ratio:1; position:relative; display:grid; place-items:center; border-radius:16px; overflow:hidden; color:white; font-size:1.35rem; font-weight:700; box-shadow:inset 0 0 0 1px rgba(255,255,255,.15); }
|
||
.agent-avatar img { width:100%; height:100%; object-fit:cover; }
|
||
.avatar-progress { position:absolute; inset:0; display:grid; place-items:center; background:rgba(0,0,0,.5); }
|
||
.agent-avatar-actions { --agent-editor-action:var(--color-primary); display:flex; align-items:center; justify-content:center; gap:.35rem; font-size:.76rem; white-space:nowrap; }
|
||
.avatar-color-action,.avatar-upload-action { position:relative; cursor:pointer; }
|
||
.avatar-action-icon { display:grid; place-items:center; width:1.75rem; height:1.75rem; border-radius:6px; color:var(--agent-editor-action); }
|
||
.avatar-action-icon x-icon { font-size:1.05rem; }
|
||
.avatar-color-action input,.avatar-upload-action input { position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }
|
||
.agent-field { display:flex; flex-direction:column; gap:.35rem; min-width:0; }
|
||
.agent-name-field { width:100%; }
|
||
.agent-field-label { font-weight:650; font-size:.92rem; }
|
||
.agent-field input,.agent-field textarea,.agent-easy textarea,.policy-filters input,.policy-filters select,.compact-search input { width:100%; box-sizing:border-box; }
|
||
.agent-field small,.agent-field-heading p,.field-status { color:var(--color-text-secondary); font-size:.79rem; }
|
||
.field-count { color:var(--color-text-secondary); font-size:.79rem; font-weight:400; }
|
||
.field-status { display:block; margin-top:.15rem; }
|
||
.field-error { display:block; color:var(--color-text); font-size:.79rem; font-weight:600; line-height:1.35; }
|
||
.agent-id-feedback { display:flex; flex-wrap:wrap; align-items:center; gap:.35rem .65rem; }
|
||
.agent-easy-field .field-error { margin-top:.35rem; }
|
||
.agent-field-heading { display:flex; justify-content:space-between; gap:1rem; align-items:flex-start; margin-bottom:.5rem; }
|
||
.agent-editor .text-button { display:inline-flex; align-items:center; min-height:1.5rem; border:0; padding:0; background:transparent; color:var(--agent-editor-action); cursor:pointer; font-size:.82rem; text-align:left; }
|
||
.agent-editor .text-button:hover { text-decoration:underline; }
|
||
.agent-easy textarea { min-height:11rem; resize:vertical; }
|
||
.restore-action { --agent-editor-action:var(--color-primary); display:inline-flex; align-items:center; gap:.25rem; margin-top:.4rem; }
|
||
.agent-easy-capabilities { display:flex; flex-direction:column; gap:.65rem; }
|
||
.future-policy-control { display:flex; align-items:center; justify-content:space-between; gap:1rem; padding:.45rem .2rem; }
|
||
.capability-policy-group + .capability-policy-group { border-top:1px solid var(--color-border); padding-top:.55rem; }
|
||
.capability-accordion summary { display:flex; align-items:center; justify-content:space-between; gap:.75rem; padding:.65rem .2rem .75rem; cursor:pointer; color:var(--color-text-secondary); font-weight:500; }
|
||
.capability-accordion summary x-icon { color:var(--color-text-secondary); transition:transform .15s ease; }
|
||
.capability-accordion[open] summary x-icon { transform:rotate(180deg); }
|
||
.capability-accordion .policy-items { max-height:none; overflow:visible; padding:0 0 .45rem; }
|
||
.agent-advanced { flex:1 1 auto; display:grid; grid-template-columns:14rem minmax(0,1fr); gap:1rem; min-height:0; }
|
||
.agent-advanced-nav { display:flex; flex-direction:column; gap:.3rem; padding:.45rem; border:1px solid var(--color-border); border-radius:10px; background:var(--color-input); align-self:start; position:sticky; top:0; }
|
||
.agent-advanced-nav button { display:grid; grid-template-columns:1.7rem 1fr auto; align-items:center; gap:.45rem; border:0; border-radius:7px; padding:.65rem; color:var(--color-text-secondary); background:transparent; text-align:left; }
|
||
.agent-advanced-nav button.active { color:var(--color-text); background:var(--color-panel); }
|
||
.section-number { display:grid; place-items:center; width:1.55rem; height:1.55rem; border:1px solid var(--color-border); border-radius:50%; font-size:.75rem; }
|
||
.agent-advanced-content,.agent-editor-workspace,.agent-manager { min-width:0; }
|
||
.agent-advanced-content { min-height:0; overflow:auto; }
|
||
.agent-advanced-content > section { outline:none; display:flex; flex-direction:column; gap:1rem; }
|
||
.agent-advanced-content > section[data-agent-editor-section="2"] { height:100%; min-height:0; }
|
||
.advanced-section-heading { display:flex; flex-direction:column; gap:.25rem; padding-bottom:.8rem; border-bottom:1px solid var(--color-border); }
|
||
.advanced-section-heading h3 { font-size:1.2rem; }
|
||
.advanced-section-heading p { max-width:48rem; color:var(--color-text-secondary); font-size:.84rem; }
|
||
.origin-row { display:flex; flex-wrap:wrap; align-items:center; gap:.6rem; }
|
||
.built-in-note,.field-provenance { color:var(--color-text-secondary); font-size:.76rem; }
|
||
.agent-origin { padding:.2rem .45rem; border:1px solid var(--color-border); border-radius:999px; font-size:.72rem; color:var(--color-text-secondary); }
|
||
.agent-editor-note { padding:.55rem .7rem; border-left:3px solid var(--color-warning); background:color-mix(in srgb,var(--color-warning) 8%,transparent); color:var(--color-text-secondary); font-size:.8rem; }
|
||
.advanced-identity-grid { display:grid; grid-template-columns:9rem minmax(0,1fr); gap:1.2rem; }
|
||
.advanced-avatar { align-self:start; }
|
||
.identity-fields { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.9rem; }
|
||
.identity-fields .agent-field.wide { grid-column:1/-1; }
|
||
.agent-model-preset-picker { width:100%; display:grid; grid-template-columns:minmax(13rem,18rem) auto; align-items:center; justify-content:space-between; gap:1rem; }
|
||
.agent-model-preset-picker select { width:100%; }
|
||
.agent-model-preset-picker > .button { display:inline-flex; align-items:center; gap:.35rem; }
|
||
.prompt-workspace { flex:1 1 auto; display:grid; grid-template-columns:minmax(13rem,16rem) minmax(0,1fr); gap:.8rem; min-width:0; min-height:0; }
|
||
.prompt-browser { display:flex; flex-direction:column; min-width:0; min-height:0; height:100%; border:1px solid var(--color-border); border-radius:10px; overflow:hidden; }
|
||
.compact-search,.policy-search { display:grid; grid-template-columns:1.25rem minmax(0,1fr); align-items:center; gap:.3rem; min-width:0; height:2.125rem; padding:0 .45rem; border:1px solid color-mix(in srgb,var(--color-border) 42%,transparent); border-radius:7px; background:color-mix(in srgb,var(--color-text) 10%,transparent); color:var(--color-text-secondary); }
|
||
.compact-search { margin:.45rem; }
|
||
.compact-search:focus-within,.policy-search:focus-within { border-color:color-mix(in srgb,var(--color-primary) 46%,var(--color-border)); background:color-mix(in srgb,var(--color-text) 13%,transparent); }
|
||
.agent-editor .compact-search input,.agent-editor .policy-search input { height:100%; min-height:0; padding:0; border:0; outline:0; appearance:none; background:transparent; }
|
||
.prompt-file-list { flex:1; overflow:auto; padding:.35rem; }
|
||
.prompt-file-group { min-width:0; margin-bottom:.55rem; }
|
||
.prompt-file-group h4 { padding:.35rem .5rem .25rem; color:var(--color-text-secondary); font-size:.7rem; font-weight:650; letter-spacing:.03em; text-transform:uppercase; }
|
||
.prompt-file-list button { width:100%; display:grid; grid-template-columns:minmax(0,1fr) auto; gap:.15rem .4rem; padding:.5rem; border:0; border-radius:6px; background:transparent; color:var(--color-text); text-align:left; }
|
||
.prompt-file-list button.active { background:var(--color-input); }
|
||
.prompt-file-name { grid-column:1/-1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-family:monospace; font-size:.76rem; }
|
||
.prompt-file-state { color:var(--color-text-secondary); font-size:.7rem; }
|
||
.prompt-empty { padding:.65rem; color:var(--color-text-secondary); font-size:.78rem; }
|
||
.prompt-editor { display:flex; flex-direction:column; gap:.55rem; min-width:0; min-height:0; max-width:100%; overflow:hidden; }
|
||
.prompt-editor-header { display:flex; justify-content:space-between; gap:.7rem; align-items:flex-start; }
|
||
.prompt-editor-header > div:first-child { min-width:0; overflow-wrap:anywhere; }
|
||
.prompt-file-heading { display:flex; flex-direction:column; gap:.25rem; }
|
||
.prompt-actions { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:.35rem; min-width:0; }
|
||
.prompt-actions .button { max-width:100%; white-space:normal; overflow-wrap:anywhere; }
|
||
.prompt-customization-path { display:flex; align-items:center; gap:.4rem; min-width:0; }
|
||
.prompt-customization-path code { min-width:0; color:var(--color-text-secondary); font-size:.72rem; overflow-wrap:anywhere; }
|
||
.prompt-customization-path .button { width:2.125rem; height:2.125rem; flex:0 0 auto; padding:0; }
|
||
.prompt-ace { flex:1; min-height:0; border:1px solid var(--color-border); border-radius:8px; overflow:hidden; font:13px/1.55 ui-monospace,SFMono-Regular,Consolas,monospace; }
|
||
.profile-maintenance summary { display:flex; align-items:center; min-height:1.5rem; cursor:pointer; }
|
||
.policy-filters { display:grid; grid-template-columns:minmax(12rem,1fr) minmax(8rem,auto); gap:.6rem; }
|
||
.policy-filters.skills { grid-template-columns:minmax(12rem,1fr) minmax(8rem,auto); }
|
||
.policy-filters label { display:flex; align-items:center; gap:.35rem; font-size:.78rem; color:var(--color-text-secondary); }
|
||
.policy-filters select { flex:1; }
|
||
.policy-group { display:flex; flex-direction:column; min-width:0; border:1px solid var(--color-border); border-radius:10px; overflow:hidden; }
|
||
.policy-group header { display:flex; align-items:center; justify-content:space-between; gap:.5rem; padding:.65rem .8rem; border-bottom:1px solid var(--color-border); background:var(--color-input); }
|
||
.policy-group header span { color:var(--color-text-secondary); font-size:.72rem; }
|
||
.policy-items { flex:1; max-height:24rem; overflow:auto; padding:.35rem; }
|
||
.policy-item { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:.75rem; align-items:start; padding:.55rem; border-radius:7px; }
|
||
.policy-item:hover { background:var(--color-input); }
|
||
.policy-item-copy { display:flex; flex-direction:column; gap:.15rem; min-width:0; }
|
||
.policy-items small { color:var(--color-text-secondary); overflow-wrap:anywhere; }
|
||
.policy-items em { color:var(--color-warning); font-size:.72rem; font-style:normal; }
|
||
.policy-item-description { margin:0; color:var(--color-text-secondary); font-size:.75rem; white-space:pre-wrap; overflow-wrap:anywhere; }
|
||
.policy-state-control { display:inline-flex; align-self:center; overflow:hidden; border:1px solid var(--color-border); border-radius:var(--border-radius-sm); background:var(--color-input); }
|
||
.policy-state-control button { min-height:2rem; padding:.35rem .6rem; border:0; border-left:1px solid var(--color-border); border-radius:0; background:transparent; color:var(--color-text-secondary); cursor:pointer; font-size:.74rem; white-space:nowrap; }
|
||
.policy-state-control button:first-child { border-left:0; }
|
||
.policy-state-control button.active { color:var(--color-text); background:#2196f3; box-shadow:0 1px 4px rgba(0,0,0,.2); }
|
||
.policy-empty { padding:1rem .7rem; color:var(--color-text-secondary); font-size:.8rem; text-align:center; }
|
||
.review-identity { display:grid; grid-template-columns:3.25rem minmax(0,1fr); align-items:center; gap:.8rem; padding:.8rem; border-bottom:1px solid var(--color-border); }
|
||
.review-identity-avatar { width:3.25rem; aspect-ratio:1; display:grid; place-items:center; overflow:hidden; border-radius:10px; color:#fff; font-weight:700; }
|
||
.review-identity-avatar img { width:100%; height:100%; object-fit:cover; }
|
||
.review-identity > div:last-child { display:flex; flex-direction:column; gap:.15rem; min-width:0; }
|
||
.review-identity strong,.review-identity p { min-width:0; overflow-wrap:anywhere; }
|
||
.review-identity p { color:var(--color-text-secondary); font-size:.8rem; }
|
||
.change-plan { display:grid; grid-template-columns:1fr 1fr; gap:.8rem; }
|
||
.change-plan section { padding:.85rem; border:1px solid var(--color-border); border-radius:9px; background:var(--color-input); min-width:0; }
|
||
.change-plan ul { margin:.55rem 0 0; padding-left:1.2rem; }
|
||
.change-plan code { overflow-wrap:anywhere; }
|
||
.review-blocked { display:flex; align-items:flex-start; gap:.65rem; padding:.8rem; border:1px solid color-mix(in srgb,var(--agent-editor-danger) 55%,var(--color-border)); border-radius:9px; background:color-mix(in srgb,var(--agent-editor-danger) 8%,var(--color-panel)); }
|
||
.review-blocked > x-icon { flex:0 0 auto; color:var(--agent-editor-danger); }
|
||
.review-blocked ul { margin:.45rem 0 0; padding-left:1.1rem; }
|
||
.review-plan-status { display:flex; flex-wrap:wrap; align-items:center; gap:.45rem; color:var(--color-text-secondary); font-size:.82rem; }
|
||
.review-actions { display:flex; flex-wrap:wrap; align-items:center; gap:.65rem; }
|
||
.profile-maintenance { display:flex; flex-direction:column; align-items:flex-start; gap:.55rem; margin-top:.5rem; padding:1rem; border:1px solid var(--color-border); border-radius:9px; }
|
||
.profile-maintenance p { color:var(--color-text-secondary); font-size:.82rem; }
|
||
.profile-maintenance details { width:100%; padding-top:.6rem; border-top:1px solid var(--color-border); }
|
||
.profile-maintenance details p { margin:.5rem 0; }
|
||
.agent-editor-footer { --agent-editor-action:var(--color-highlight); width:100%; display:flex; justify-content:space-between; gap:.7rem; }
|
||
.footer-actions { display:flex; gap:.5rem; margin-left:auto; }
|
||
.agent-editor-footer .btn-cancel,.agent-editor-secondary-action { border:1px solid var(--color-border); background:transparent; color:var(--color-text); }
|
||
.agent-editor-footer .btn-cancel:hover,.agent-editor-secondary-action:hover { border-color:color-mix(in srgb,var(--agent-editor-action) 50%,var(--color-border)); background:color-mix(in srgb,var(--agent-editor-action) 10%,transparent); color:var(--color-text); }
|
||
.agent-editor-secondary-action { display:inline-flex; align-items:center; }
|
||
.agent-editor .button.danger { display:inline-flex; align-items:center; gap:.35rem; border-color:color-mix(in srgb,var(--agent-editor-danger) 60%,var(--color-border)); color:var(--agent-editor-danger); background:color-mix(in srgb,var(--agent-editor-danger) 7%,var(--color-panel)); }
|
||
.agent-editor .button.danger:hover { background:color-mix(in srgb,var(--agent-editor-danger) 15%,var(--color-panel)); }
|
||
.agent-manager { display:flex; flex-direction:column; gap:1rem; }
|
||
.agent-scope-selector { padding:.75rem 1rem; border:1px solid var(--color-border); border-radius:4px; }
|
||
.agent-scope-field { display:flex; flex:1 1 0; align-items:center; gap:.5rem; min-width:12rem; margin:0; }
|
||
.agent-scope-field span { color:var(--color-text-secondary); font-weight:600; white-space:nowrap; }
|
||
.agent-scope-field select { flex:1 1 auto; min-width:0; }
|
||
.agent-editor-scope { flex:0 1 24rem; }
|
||
.agent-manager-copy p { color:var(--color-text-secondary); font-size:.82rem; }
|
||
.agent-manager-list-header { display:flex; align-items:center; justify-content:flex-end; gap:1rem; }
|
||
.active-agent-display { display:flex; align-items:center; gap:.5rem; min-width:0; margin-right:auto; padding:.5rem; border:1px solid var(--color-highlight); border-radius:.5rem; }
|
||
.active-agent-summary { display:flex; align-items:center; gap:.5rem; min-width:0; }
|
||
.active-agent-summary strong { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
||
.active-agent-avatar { width:1.5rem; aspect-ratio:1; display:grid; flex:0 0 auto; place-items:center; overflow:hidden; border-radius:6px; color:#fff; font-size:.65rem; font-weight:700; }
|
||
.active-agent-avatar img { width:100%; height:100%; object-fit:cover; }
|
||
.agent-manager-create { flex:0 0 auto; display:inline-flex; align-items:center; gap:.35rem; }
|
||
.agent-manager-list { display:flex; flex-direction:column; }
|
||
.agent-manager-card { display:grid; grid-template-columns:3rem minmax(0,1fr) auto; gap:.75rem; align-items:center; padding:.65rem .25rem; }
|
||
.agent-manager-card + .agent-manager-card { border-top:1px solid var(--color-border); }
|
||
.agent-manager-avatar { width:3rem; aspect-ratio:1; display:grid; place-items:center; border-radius:10px; color:white; font-weight:700; overflow:hidden; }
|
||
.agent-manager-avatar img { width:100%; height:100%; object-fit:cover; }
|
||
.agent-manager-copy { min-width:0; }
|
||
.agent-manager-name { display:flex; flex-wrap:wrap; align-items:center; gap:.4rem; }
|
||
.agent-manager-name strong,.agent-manager-copy p { overflow-wrap:anywhere; }
|
||
.agent-editor .agent-manager-inline-action { gap:.25rem; margin-top:.15rem; color:var(--color-message-text); opacity:.7; }
|
||
.agent-editor .agent-manager-inline-action + .agent-manager-inline-action { margin-left:.5rem; }
|
||
.agent-editor .agent-manager-inline-action:hover:not(:disabled) { background:transparent; color:var(--color-text); text-decoration:none; opacity:1; }
|
||
.agent-manager-actions { display:flex; flex-wrap:wrap; align-items:center; gap:.4rem; }
|
||
.agent-profile-availability input { width:0; height:0; margin:0; border:0; }
|
||
.sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }
|
||
.agent-editor :focus-visible { outline:2px solid var(--agent-editor-action); outline-offset:2px; }
|
||
.modal-inner.agent-editor-easy { width:min(720px,calc(100vw - 2rem)); max-width:720px; }
|
||
.modal-inner.agent-editor-advanced { width:92vw; max-width:none; height:min(calc(100vh - 4rem),80rem); max-height:calc(100vh - 4rem); }
|
||
.modal-inner.agent-editor-advanced .modal-scroll,.modal-inner.agent-editor-advanced .modal-bd,.modal-inner.agent-editor-advanced .agent-editor,.modal-inner.agent-editor-advanced .agent-editor-workspace { display:flex; flex:1 1 auto; min-height:0; }
|
||
.modal-inner.agent-editor-advanced .modal-scroll { max-height:none; }
|
||
.modal-inner.agent-editor-advanced .agent-editor,.modal-inner.agent-editor-advanced .agent-editor-workspace { flex-direction:column; }
|
||
@media (max-width: 760px) {
|
||
.modal-inner.agent-editor-easy,.modal-inner.agent-editor-advanced { width:100vw; max-width:none; height:100vh; max-height:none; border-radius:0; }
|
||
.agent-editor-topbar { align-items:flex-start; flex-wrap:wrap; }
|
||
.agent-editor-heading { width:100%; }
|
||
.agent-editor-topbar-actions { width:100%; flex-wrap:wrap; justify-content:flex-end; }
|
||
.agent-editor-scope { flex:1 1 14rem; }
|
||
.agent-easy-identity { grid-template-columns:1fr; justify-items:center; padding-top:1.8rem; }
|
||
.agent-id-feedback { width:100%; }
|
||
.agent-advanced { grid-template-columns:1fr; }
|
||
.agent-advanced-nav { position:static; flex-direction:row; overflow-x:auto; }
|
||
.agent-advanced-nav button { grid-template-columns:auto auto auto; white-space:nowrap; }
|
||
.agent-model-preset-picker { grid-template-columns:minmax(0,1fr) auto; gap:.5rem; }
|
||
.prompt-workspace { grid-template-columns:1fr; }
|
||
.prompt-browser { height:22rem; max-height:22rem; }
|
||
.prompt-editor { max-height:none; overflow:visible; }
|
||
.prompt-ace { min-height:18rem; }
|
||
.change-plan,.advanced-identity-grid,.identity-fields { grid-template-columns:1fr; }
|
||
.identity-fields .agent-field.wide { grid-column:1; }
|
||
.policy-filters { grid-template-columns:1fr; }
|
||
.future-policy-control { align-items:flex-start; }
|
||
.policy-item { grid-template-columns:1fr; }
|
||
.policy-state-control { width:100%; align-self:stretch; }
|
||
.policy-state-control button { flex:1; }
|
||
.agent-manager-list-header { flex-wrap:wrap; }
|
||
.active-agent-display { width:100%; }
|
||
.agent-manager-create { margin-left:auto; }
|
||
.agent-manager-card { grid-template-columns:3rem minmax(0,1fr) auto; align-items:start; }
|
||
.agent-manager-actions { grid-column:auto; align-self:stretch; display:grid; grid-template-columns:auto auto; align-content:space-between; justify-content:end; justify-items:end; }
|
||
.agent-manager-actions .agent-profile-availability { grid-column:1/-1; }
|
||
.agent-scope-field { flex-basis:100%; min-width:0; }
|
||
.agent-editor-footer { flex-wrap:wrap; }
|
||
.footer-actions { width:auto; max-width:100%; flex-wrap:wrap; justify-content:flex-end; }
|
||
.footer-actions .btn { flex:0 1 auto; text-align:center; }
|
||
}
|
||
</style>
|
||
</body>
|
||
</html>
|