Compare commits

...

3 Commits

Author SHA1 Message Date
ee03b34c41 docs: AGENTS.md 设计规范新增大面积色块禁纯黑条款 2026-08-11 23:39:02 +08:00
492b738859 refactor(ui): 打勾框收敛为 FancyCheck 单一组件并修复残缺路径
- 新增 components/common/FancyCheck.vue 作为全局唯一打勾框实现(checked/size/accent-checked)
- 修复个人空间「编辑摘要实时显示」开关 d 路径中段缺失导致对勾渲染变长
- 38 处内联 SVG 全部改为组件引用,删除四处重复的 fancy 样式
2026-08-11 23:39:01 +08:00
79f8ffa368 feat(chat): 编辑摘要卡片弹窗改为锚定定位并修复深色近黑样式
- 弹窗水平相对编辑卡片居中,垂直优先锚定条目上方(空间不足自动翻到下方),高度吃满可用空间
- 行 hover 改用 --hover-bg(深色提亮),弹窗头部去近黑衬底改用分隔线
- 行高亮 is-active 仅钉住态挂载,修复 hover 消失延迟
2026-08-11 23:38:47 +08:00
7 changed files with 227 additions and 474 deletions

View File

@ -199,6 +199,7 @@
8. **窗口设最大尺寸 + 内部滚动**:所有弹窗 / 面板 / 列表设置 `max-height` / `max-width`,超出由内部容器滚动,不顶大整个窗口;滚动条要么隐藏,要么做样式适配,不暴露原生粗滚动条。 8. **窗口设最大尺寸 + 内部滚动**:所有弹窗 / 面板 / 列表设置 `max-height` / `max-width`,超出由内部容器滚动,不顶大整个窗口;滚动条要么隐藏,要么做样式适配,不暴露原生粗滚动条。
9. **实体面板禁止半透明**:实体 UI 容器(对话区 / 侧栏 / 下拉/二级菜单 / 抽屉 / 对话框本体 / 状态条 / tooltip / 输入栏)背景必须不透明,且不加 `backdrop-filter` 磨砂。唯一例外:遮罩层 scrim`--overlay-scrim``position:fixed;inset:0`)和刻意玻璃质感装饰保留半透明。 9. **实体面板禁止半透明**:实体 UI 容器(对话区 / 侧栏 / 下拉/二级菜单 / 抽屉 / 对话框本体 / 状态条 / tooltip / 输入栏)背景必须不透明,且不加 `backdrop-filter` 磨砂。唯一例外:遮罩层 scrim`--overlay-scrim``position:fixed;inset:0`)和刻意玻璃质感装饰保留半透明。
10. **主题变体必须与基础定义同文件(禁止跨文件补丁覆盖)**:组件的 dark/light/classic 主题变体写在该组件自己的样式文件里(文件内统一的 `body[data-theme='…'] { … }` 块),禁止把某组件的主题样式写到别的文件去覆盖。新增主题样式前先确认该组件基础定义所在文件;发现存量跨文件覆盖应顺手回迁并删除原覆盖。`!important` 只准用于遮盖第三方库样式,禁止用于压过项目自有定义(出现这种需求说明应该合并定义,而不是加 `!important`)。审计脚本:`python3 cache/style_audit.py` + `python3 cache/theme_diff.py` 10. **主题变体必须与基础定义同文件(禁止跨文件补丁覆盖)**:组件的 dark/light/classic 主题变体写在该组件自己的样式文件里(文件内统一的 `body[data-theme='…'] { … }` 块),禁止把某组件的主题样式写到别的文件去覆盖。新增主题样式前先确认该组件基础定义所在文件;发现存量跨文件覆盖应顺手回迁并删除原覆盖。`!important` 只准用于遮盖第三方库样式,禁止用于压过项目自有定义(出现这种需求说明应该合并定义,而不是加 `!important`)。审计脚本:`python3 cache/style_audit.py` + `python3 cache/theme_diff.py`
11. **大面积色块禁止纯黑/近黑**:任何窗口的 hover、头部、背景等大面积色块禁止使用纯黑`#000`)或肉眼近黑(如 `#0a0a0a`/`#0f0f0f` 一档的颜色深色模式同样如此。深色下的层次靠中性灰阶拉开hover 用 `--hover-bg`(深色为白色微量 tint提亮而非压黑弹窗/面板头部优先用分隔线区分而非深色衬底(参考 `VersioningDialog.vue` 头部)。纯黑/近黑只允许用于小范围强调渲染(如行内代码衬底等小面积场景)。
## 5.6) 工具结果显示规范(强制) ## 5.6) 工具结果显示规范(强制)

View File

@ -109,15 +109,7 @@
:checked="getCategoryDefault(cat.id)" :checked="getCategoryDefault(cat.id)"
@change="setCategoryDefault(cat.id, $event.target.checked)" @change="setCategoryDefault(cat.id, $event.target.checked)"
/> />
<span class="fancy-check" aria-hidden="true"> <FancyCheck :checked="getCategoryDefault(cat.id)" accent-checked />
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>{{ cat.default_enabled ? '开' : '关' }}</span> <span>{{ cat.default_enabled ? '开' : '关' }}</span>
</label> </label>
<div class="dropdown" :class="{ open: openForceMenu === cat.id }"> <div class="dropdown" :class="{ open: openForceMenu === cat.id }">
@ -144,15 +136,7 @@
<div class="toggle-grid"> <div class="toggle-grid">
<label v-for="model in defaults.models" :key="model" class="toggle-row"> <label v-for="model in defaults.models" :key="model" class="toggle-row">
<input type="checkbox" :checked="isModelDisabled(model)" @change="toggleModel(model)" /> <input type="checkbox" :checked="isModelDisabled(model)" @change="toggleModel(model)" />
<span class="fancy-check" aria-hidden="true"> <FancyCheck :checked="isModelDisabled(model)" accent-checked />
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>{{ model }}</span> <span>{{ model }}</span>
</label> </label>
</div> </div>
@ -168,15 +152,7 @@
:checked="!!form.config.ui_blocks[key]" :checked="!!form.config.ui_blocks[key]"
@change="toggleUiBlock(key, $event)" @change="toggleUiBlock(key, $event)"
/> />
<span class="fancy-check" aria-hidden="true"> <FancyCheck :checked="!!form.config.ui_blocks[key]" accent-checked />
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
<span>{{ uiBlockLabel(key) }}</span> <span>{{ uiBlockLabel(key) }}</span>
</label> </label>
</div> </div>
@ -313,6 +289,7 @@
import { computed, reactive, ref, onMounted, onBeforeUnmount, watch } from 'vue'; import { computed, reactive, ref, onMounted, onBeforeUnmount, watch } from 'vue';
import { useSecondaryPass } from './useSecondaryPass'; import { useSecondaryPass } from './useSecondaryPass';
import SecondaryGate from './SecondaryGate.vue'; import SecondaryGate from './SecondaryGate.vue';
import FancyCheck from '@/components/common/FancyCheck.vue';
type TargetType = 'global' | 'role' | 'user' | 'invite'; type TargetType = 'global' | 'role' | 'user' | 'invite';
@ -1367,43 +1344,6 @@ button:disabled {
pointer-events: none; pointer-events: none;
} }
.toggle-row .fancy-check {
width: 28px;
height: 28px;
border-radius: 6px;
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow: none;
background: transparent;
}
.toggle-row .fancy-check svg {
width: 22px;
height: 22px;
overflow: visible;
}
.fancy-path {
fill: none;
stroke: var(--text-secondary);
stroke-width: 5;
stroke-linecap: round;
stroke-linejoin: round;
transition:
stroke-dasharray 0.5s ease,
stroke-dashoffset 0.5s ease,
stroke 0.2s ease;
stroke-dasharray: 241 9999999;
stroke-dashoffset: 0;
}
.toggle-row input:checked + .fancy-check .fancy-path {
stroke: var(--accent);
stroke-dasharray: 70.5096664428711 9999999;
stroke-dashoffset: -262.2723388671875;
}
.toggle-row span { .toggle-row span {
color: var(--text-primary); color: var(--text-primary);
font-weight: 600; font-weight: 600;

View File

@ -49,6 +49,11 @@ const totals = computed(() => {
// ---------------- ---------------- // ---------------- ----------------
const activePath = ref<string | null>(null); const activePath = ref<string | null>(null);
const pinned = ref(false); const pinned = ref(false);
const cardRef = ref<HTMLElement | null>(null);
const anchorEl = ref<HTMLElement | null>(null);
//
// 退 CSS
const panelStyle = ref<Record<string, string>>({});
let openTimer: ReturnType<typeof setTimeout> | null = null; let openTimer: ReturnType<typeof setTimeout> | null = null;
let closeTimer: ReturnType<typeof setTimeout> | null = null; let closeTimer: ReturnType<typeof setTimeout> | null = null;
@ -57,6 +62,76 @@ const activeFile = computed<SummaryFile | null>(() => {
return files.value.find((f) => f.path === activePath.value) || null; return files.value.find((f) => f.path === activePath.value) || null;
}); });
// ---------------- ----------------
const PANEL_MAX_WIDTH = 720;
const VIEWPORT_MARGIN = 16;
const MIN_PANEL_HEIGHT = 140;
//
const PREFER_ABOVE_MIN_HEIGHT = 260;
function computePanelStyle() {
if (isMobile.value || !cardRef.value || !anchorEl.value) {
// / 退 CSS
panelStyle.value = {};
return;
}
const vw = window.innerWidth;
const vh = window.innerHeight;
const width = Math.min(PANEL_MAX_WIDTH, vw - VIEWPORT_MARGIN * 2);
//
const cardRect = cardRef.value.getBoundingClientRect();
const centerX = cardRect.left + cardRect.width / 2;
const left = Math.min(
Math.max(centerX - width / 2, VIEWPORT_MARGIN),
vw - width - VIEWPORT_MARGIN
);
// = -
// = +
//
const rowRect = anchorEl.value.getBoundingClientRect();
const anchorAbove = rowRect.top - rowRect.height / 2;
const anchorBelow = rowRect.bottom + rowRect.height / 2;
const spaceAbove = anchorAbove - VIEWPORT_MARGIN;
const spaceBelow = vh - VIEWPORT_MARGIN - anchorBelow;
const placeAbove = spaceAbove >= PREFER_ABOVE_MIN_HEIGHT || spaceAbove >= spaceBelow;
const base: Record<string, string> = {
left: `${Math.round(left)}px`,
width: `${Math.round(width)}px`,
transform: 'none'
};
if (placeAbove) {
const bottomEdge = Math.min(
Math.max(anchorAbove, VIEWPORT_MARGIN + MIN_PANEL_HEIGHT),
vh - VIEWPORT_MARGIN
);
panelStyle.value = {
...base,
top: 'auto',
bottom: `${Math.round(vh - bottomEdge)}px`,
maxHeight: `${Math.round(bottomEdge - VIEWPORT_MARGIN)}px`
};
} else {
const topEdge = Math.min(
Math.max(anchorBelow, VIEWPORT_MARGIN),
vh - VIEWPORT_MARGIN - MIN_PANEL_HEIGHT
);
panelStyle.value = {
...base,
top: `${Math.round(topEdge)}px`,
bottom: 'auto',
maxHeight: `${Math.round(vh - VIEWPORT_MARGIN - topEdge)}px`
};
}
}
function onWindowReposition() {
if (!activePath.value) return;
computePanelStyle();
}
function clearOpenTimer() { function clearOpenTimer() {
if (openTimer) { if (openTimer) {
clearTimeout(openTimer); clearTimeout(openTimer);
@ -71,16 +146,18 @@ function clearCloseTimer() {
} }
} }
function open(path: string, pin: boolean) { function open(path: string, pin: boolean, rowEl: HTMLElement | null = null) {
clearOpenTimer(); clearOpenTimer();
clearCloseTimer(); clearCloseTimer();
activePath.value = path; activePath.value = path;
pinned.value = pin; pinned.value = pin;
anchorEl.value = rowEl;
computePanelStyle();
} }
function scheduleOpen(path: string) { function scheduleOpen(path: string, rowEl: HTMLElement | null) {
clearOpenTimer(); clearOpenTimer();
openTimer = setTimeout(() => open(path, false), 150); openTimer = setTimeout(() => open(path, false, rowEl), 150);
} }
function scheduleClose() { function scheduleClose() {
@ -91,10 +168,10 @@ function scheduleClose() {
}, 200); }, 200);
} }
function onRowMouseEnter(path: string) { function onRowMouseEnter(path: string, e: MouseEvent) {
if (isMobile.value) return; if (isMobile.value) return;
clearCloseTimer(); clearCloseTimer();
scheduleOpen(path); scheduleOpen(path, (e.currentTarget as HTMLElement) || null);
} }
function onRowMouseLeave() { function onRowMouseLeave() {
@ -111,9 +188,9 @@ function onPanelMouseLeave() {
if (!isMobile.value) scheduleClose(); if (!isMobile.value) scheduleClose();
} }
function onRowClick(path: string) { function onRowClick(path: string, e: MouseEvent) {
// = hover // = hover
open(path, true); open(path, true, (e.currentTarget as HTMLElement) || null);
} }
function close() { function close() {
@ -121,6 +198,7 @@ function close() {
clearCloseTimer(); clearCloseTimer();
pinned.value = false; pinned.value = false;
activePath.value = null; activePath.value = null;
anchorEl.value = null;
} }
function onKeydown(e: KeyboardEvent) { function onKeydown(e: KeyboardEvent) {
@ -132,8 +210,13 @@ function onKeydown(e: KeyboardEvent) {
watch(activePath, (v) => { watch(activePath, (v) => {
if (v) { if (v) {
window.addEventListener('keydown', onKeydown); window.addEventListener('keydown', onKeydown);
window.addEventListener('resize', onWindowReposition);
//
window.addEventListener('scroll', onWindowReposition, true);
} else { } else {
window.removeEventListener('keydown', onKeydown); window.removeEventListener('keydown', onKeydown);
window.removeEventListener('resize', onWindowReposition);
window.removeEventListener('scroll', onWindowReposition, true);
} }
}); });
@ -141,6 +224,8 @@ onBeforeUnmount(() => {
clearOpenTimer(); clearOpenTimer();
clearCloseTimer(); clearCloseTimer();
window.removeEventListener('keydown', onKeydown); window.removeEventListener('keydown', onKeydown);
window.removeEventListener('resize', onWindowReposition);
window.removeEventListener('scroll', onWindowReposition, true);
}); });
// ---------------- diff ---------------- // ---------------- diff ----------------
@ -163,7 +248,7 @@ function lineNumber(line: any): string {
</script> </script>
<template> <template>
<div v-if="files.length" class="edit-summary-card"> <div v-if="files.length" class="edit-summary-card" ref="cardRef">
<div class="edit-summary-card__header"> <div class="edit-summary-card__header">
<span <span
class="icon icon-sm edit-summary-card__icon" class="icon icon-sm edit-summary-card__icon"
@ -181,10 +266,10 @@ function lineNumber(line: any): string {
v-for="file in files" v-for="file in files"
:key="file.path" :key="file.path"
class="edit-summary-card__row" class="edit-summary-card__row"
:class="{ 'is-active': activePath === file.path }" :class="{ 'is-active': pinned && activePath === file.path }"
@mouseenter="onRowMouseEnter(file.path)" @mouseenter="onRowMouseEnter(file.path, $event)"
@mouseleave="onRowMouseLeave" @mouseleave="onRowMouseLeave"
@click.stop="onRowClick(file.path)" @click.stop="onRowClick(file.path, $event)"
> >
<span class="edit-summary-card__path" :title="file.path">{{ file.path }}</span> <span class="edit-summary-card__path" :title="file.path">{{ file.path }}</span>
<span class="edit-summary-card__delta"> <span class="edit-summary-card__delta">
@ -205,6 +290,7 @@ function lineNumber(line: any): string {
></div> ></div>
<div <div
class="es-modal__panel" class="es-modal__panel"
:style="panelStyle"
role="dialog" role="dialog"
:aria-label="`文件变更:${activeFile.path}`" :aria-label="`文件变更:${activeFile.path}`"
@mouseenter="onPanelMouseEnter" @mouseenter="onPanelMouseEnter"
@ -313,9 +399,12 @@ function lineNumber(line: any): string {
font-size: 12.5px; font-size: 12.5px;
} }
/* is-active hover
否则鼠标离开后会被 200ms 关闭计时器拖住看起来像 hover 消失有延迟 */
.edit-summary-card__row:hover, .edit-summary-card__row:hover,
.edit-summary-card__row.is-active { .edit-summary-card__row.is-active {
background: var(--surface-soft); /* 用全局 hover token深色下是白色微量 tint提亮避免 surface-soft 的近黑衬底 */
background: var(--hover-bg);
} }
.edit-summary-card__path { .edit-summary-card__path {
@ -374,8 +463,8 @@ function lineNumber(line: any): string {
height: 44px; height: 44px;
padding: 0 12px; padding: 0 12px;
flex: none; flex: none;
/* 与版本管理弹窗一致:头部不加衬底,靠分隔线区分(深色下避免近黑色块) */
border-bottom: 1px solid var(--border-default); border-bottom: 1px solid var(--border-default);
background: var(--surface-soft);
} }
.es-modal__header-icon { .es-modal__header-icon {

View File

@ -0,0 +1,83 @@
<script setup lang="ts">
/**
* 打勾框fancy-check全局唯一的自定义 checkbox 图标实现
*
* 未勾选时描出圆角方框轮廓勾选时同一条路径通过 dasharray/offset
* 动画变形为对勾所有开关统一引用本组件禁止再内联复制 SVG
*
* 用法
* <label class="xxx-toggle-row">
* <input type="checkbox" :checked="form.x" @change="..." />
* <FancyCheck :checked="form.x" />
* </label>
*
* - checked与配套 input checked 保持一致本组件不处理交互仅渲染
* - sizesvg 边长默认 22小号场景默认标记 14
* - accent-checked勾选后描边变为 --accent 强调色默认不变色仅形状变形
*/
withDefaults(
defineProps<{
checked?: boolean;
size?: number;
accentChecked?: boolean;
}>(),
{
checked: false,
size: 22,
accentChecked: false
}
);
</script>
<template>
<span
class="fancy-check"
:class="{ 'is-checked': checked, 'accent-checked': accentChecked }"
aria-hidden="true"
>
<svg viewBox="0 0 64 64" :style="{ width: `${size}px`, height: `${size}px` }">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
</template>
<style scoped>
.fancy-check {
display: inline-flex;
align-items: center;
justify-content: center;
flex: none;
}
.fancy-check svg {
display: block;
overflow: visible;
}
.fancy-path {
fill: none;
stroke: var(--text-secondary);
stroke-width: 5;
stroke-linecap: round;
stroke-linejoin: round;
transition:
stroke-dasharray 0.5s ease,
stroke-dashoffset 0.5s ease,
stroke 0.2s ease;
stroke-dasharray: 241 9999999;
stroke-dashoffset: 0;
}
.fancy-check.is-checked .fancy-path {
stroke-dasharray: 70.5096664428711 9999999;
stroke-dashoffset: -262.2723388671875;
}
.fancy-check.is-checked.accent-checked .fancy-path {
stroke: var(--accent);
}
</style>

View File

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import type { ReasoningEffort } from '../../stores/personalization'; import type { ReasoningEffort } from '../../stores/personalization';
import FancyCheck from '../common/FancyCheck.vue';
const LEVELS: ReasoningEffort[] = ['low', 'medium', 'high', 'xhigh', 'max']; const LEVELS: ReasoningEffort[] = ['low', 'medium', 'high', 'xhigh', 'max'];
// inset(23) 3px // inset(23) 3px
@ -215,15 +216,7 @@ onBeforeUnmount(() => {
<span class="header-title">推理强度</span> <span class="header-title">推理强度</span>
<span class="default-toggle" :class="{ checked: isDefault }" @click.stop="toggleDefault"> <span class="default-toggle" :class="{ checked: isDefault }" @click.stop="toggleDefault">
<span class="default-label">默认</span> <span class="default-label">默认</span>
<span class="fancy-check" aria-hidden="true"> <FancyCheck :checked="isDefault" :size="14" />
<svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path>
</svg>
</span>
</span> </span>
</div> </div>
<div class="header-state header-drag"> <div class="header-state header-drag">
@ -334,35 +327,6 @@ onBeforeUnmount(() => {
font-size: 12px; font-size: 12px;
color: var(--text-secondary); color: var(--text-secondary);
} }
.default-toggle .fancy-check {
width: 18px;
height: 18px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.default-toggle .fancy-check svg {
width: 14px;
height: 14px;
overflow: visible;
}
.fancy-path {
fill: none;
stroke: var(--text-secondary);
stroke-width: 5;
stroke-linecap: round;
stroke-linejoin: round;
transition:
stroke-dasharray 0.5s ease,
stroke-dashoffset 0.5s ease,
stroke 0.2s ease;
stroke-dasharray: 241 9999999;
stroke-dashoffset: 0;
}
.default-toggle.checked .fancy-path {
stroke-dasharray: 70.5096664428711 9999999;
stroke-dashoffset: -262.2723388671875;
}
/* ========== 滑块区域 ========== */ /* ========== 滑块区域 ========== */
.slider-zone { .slider-zone {

View File

@ -98,14 +98,7 @@
}) })
" "
/> />
<span class="fancy-check" aria-hidden="true" <FancyCheck :checked="form.auto_generate_title" />
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label> </label>
<div class="settings-action-row"> <div class="settings-action-row">
<span class="settings-row-copy"> <span class="settings-row-copy">
@ -184,14 +177,7 @@
:disabled="toggleUpdating" :disabled="toggleUpdating"
@change="personalization.toggleEnabled()" @change="personalization.toggleEnabled()"
/> />
<span class="fancy-check" aria-hidden="true" <FancyCheck :checked="form.enabled" />
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label> </label>
<label class="settings-input-row"> <label class="settings-input-row">
<span class="settings-row-title">AI 智能体自称</span> <span class="settings-row-title">AI 智能体自称</span>
@ -296,14 +282,7 @@
:checked="stackedHideBorders" :checked="stackedHideBorders"
@change="handleStackedHideBordersChange($event)" @change="handleStackedHideBordersChange($event)"
/> />
<span class="fancy-check" aria-hidden="true" <FancyCheck :checked="stackedHideBorders" />
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label> </label>
<label <label
v-if="currentBlockDisplayMode === 'minimal'" v-if="currentBlockDisplayMode === 'minimal'"
@ -318,14 +297,7 @@
:checked="minimalExpandHeightLimited" :checked="minimalExpandHeightLimited"
@change="handleMinimalExpandHeightLimitedChange($event)" @change="handleMinimalExpandHeightLimitedChange($event)"
/> />
<span class="fancy-check" aria-hidden="true" <FancyCheck :checked="minimalExpandHeightLimited" />
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label> </label>
<div class="settings-select-row"> <div class="settings-select-row">
<span class="settings-row-copy"> <span class="settings-row-copy">
@ -617,14 +589,7 @@
key: 'group_sidebar_by_workspace', key: 'group_sidebar_by_workspace',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.group_sidebar_by_workspace" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">新建对话跳转空白页</span ><span class="settings-row-title">新建对话跳转空白页</span
@ -639,14 +604,7 @@
key: 'new_chat_button_behavior', key: 'new_chat_button_behavior',
value: $event.target.checked ? 'route' : 'blank' value: $event.target.checked ? 'route' : 'blank'
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.new_chat_button_behavior === 'route'" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">使用自定义称呼</span ><span class="settings-row-title">使用自定义称呼</span
@ -661,14 +619,7 @@
key: 'use_custom_names', key: 'use_custom_names',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.use_custom_names" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">增强工具显示</span ><span class="settings-row-title">增强工具显示</span
@ -683,14 +634,7 @@
key: 'enhanced_tool_display', key: 'enhanced_tool_display',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.enhanced_tool_display" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">显示助手状态形象</span ><span class="settings-row-title">显示助手状态形象</span
@ -705,14 +649,7 @@
key: 'show_status_avatar', key: 'show_status_avatar',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.show_status_avatar" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">显示 Git 状态栏</span ><span class="settings-row-title">显示 Git 状态栏</span
@ -727,14 +664,7 @@
key: 'show_git_status_bar', key: 'show_git_status_bar',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.show_git_status_bar" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">自动打开终端面板</span ><span class="settings-row-title">自动打开终端面板</span
@ -749,14 +679,7 @@
key: 'auto_open_terminal_panel', key: 'auto_open_terminal_panel',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.auto_open_terminal_panel" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">快捷窗口自动展开</span ><span class="settings-row-title">快捷窗口自动展开</span
@ -771,14 +694,7 @@
key: 'quick_dock_auto_expand', key: 'quick_dock_auto_expand',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.quick_dock_auto_expand" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">编辑摘要实时显示</span ><span class="settings-row-title">编辑摘要实时显示</span
@ -793,14 +709,7 @@
key: 'edit_summary_live_display', key: 'edit_summary_live_display',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.edit_summary_live_display" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">预览窗口自动换行显示</span ><span class="settings-row-title">预览窗口自动换行显示</span
@ -815,14 +724,7 @@
key: 'file_preview_auto_wrap', key: 'file_preview_auto_wrap',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.file_preview_auto_wrap" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div class="settings-select-row"> <div class="settings-select-row">
<span class="settings-row-copy" <span class="settings-row-copy"
><span class="settings-row-title">堆叠块显示模式</span ><span class="settings-row-title">堆叠块显示模式</span
@ -873,14 +775,7 @@
:checked="stackedHideBorders" :checked="stackedHideBorders"
@change="handleStackedHideBordersChange($event)" @change="handleStackedHideBordersChange($event)"
/> />
<span class="fancy-check" aria-hidden="true" <FancyCheck :checked="stackedHideBorders" />
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label> </label>
<label <label
v-if="currentBlockDisplayMode === 'minimal'" v-if="currentBlockDisplayMode === 'minimal'"
@ -895,14 +790,7 @@
:checked="minimalExpandHeightLimited" :checked="minimalExpandHeightLimited"
@change="handleMinimalExpandHeightLimitedChange($event)" @change="handleMinimalExpandHeightLimitedChange($event)"
/> />
<span class="fancy-check" aria-hidden="true" <FancyCheck :checked="minimalExpandHeightLimited" />
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg
></span>
</label> </label>
<div class="settings-select-row"> <div class="settings-select-row">
<span class="settings-row-copy" <span class="settings-row-copy"
@ -1002,14 +890,7 @@
key: 'agents_md_auto_inject', key: 'agents_md_auto_inject',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.agents_md_auto_inject" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div class="settings-section-divider"> <div class="settings-section-divider">
<span class="settings-section-divider__label">版本控制</span> <span class="settings-section-divider__label">版本控制</span>
@ -1029,14 +910,7 @@
key: 'versioning_enabled_by_default', key: 'versioning_enabled_by_default',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.versioning_enabled_by_default" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div class="settings-select-row"> <div class="settings-select-row">
<span class="settings-row-copy" <span class="settings-row-copy"
@ -1102,14 +976,7 @@
key: 'goal_review_mode', key: 'goal_review_mode',
value: $event.target.checked ? 'active' : 'readonly' value: $event.target.checked ? 'active' : 'readonly'
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.goal_review_mode === 'active'" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div class="settings-select-row"> <div class="settings-select-row">
<span class="settings-row-copy" <span class="settings-row-copy"
@ -1142,16 +1009,7 @@
><input ><input
type="checkbox" type="checkbox"
:checked="goalTokenLimitEnabled" :checked="goalTokenLimitEnabled"
@change="toggleGoalTokenLimit($event.target.checked)" /><span @change="toggleGoalTokenLimit($event.target.checked)" /><FancyCheck :checked="goalTokenLimitEnabled" /></label>
class="fancy-check"
aria-hidden="true"
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div v-if="goalTokenLimitEnabled" class="settings-select-row"> <div v-if="goalTokenLimitEnabled" class="settings-select-row">
<span class="settings-row-copy" <span class="settings-row-copy"
@ -1193,14 +1051,7 @@
key: 'recent_conversations_prompt_enabled', key: 'recent_conversations_prompt_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.recent_conversations_prompt_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div <div
class="settings-input-row" class="settings-input-row"
v-if="form.recent_conversations_prompt_enabled" v-if="form.recent_conversations_prompt_enabled"
@ -1237,14 +1088,7 @@
key: 'auto_shallow_compress_enabled', key: 'auto_shallow_compress_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.auto_shallow_compress_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row inner" <label class="settings-toggle-row inner"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">自动深层压缩</span></span ><span class="settings-row-title">自动深层压缩</span></span
@ -1256,14 +1100,7 @@
key: 'auto_deep_compress_enabled', key: 'auto_deep_compress_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.auto_deep_compress_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div class="settings-compression-grid"> <div class="settings-compression-grid">
<label <label
><span>浅压缩触发上下文</span ><span>浅压缩触发上下文</span
@ -1349,14 +1186,7 @@
key: 'deep_compress_form', key: 'deep_compress_form',
value: $event.target.checked ? 'inject' : 'file' value: $event.target.checked ? 'inject' : 'file'
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.deep_compress_form === 'inject'" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div class="settings-inline-actions right"> <div class="settings-inline-actions right">
<button <button
type="button" type="button"
@ -1384,14 +1214,7 @@
key: 'silent_tool_disable', key: 'silent_tool_disable',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.silent_tool_disable" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">隐藏工具审核面板</span ><span class="settings-row-title">隐藏工具审核面板</span
@ -1406,14 +1229,7 @@
key: 'hide_tool_approval_panel', key: 'hide_tool_approval_panel',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.hide_tool_approval_panel" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">工具意图提示</span ><span class="settings-row-title">工具意图提示</span
@ -1428,14 +1244,7 @@
key: 'tool_intent_enabled', key: 'tool_intent_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.tool_intent_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row" <label class="settings-toggle-row"
><span class="settings-row-copy" ><span class="settings-row-copy"
><span class="settings-row-title">Skill 提示系统</span ><span class="settings-row-title">Skill 提示系统</span
@ -1450,14 +1259,7 @@
key: 'skill_hints_enabled', key: 'skill_hints_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.skill_hints_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<div class="settings-group-block"> <div class="settings-group-block">
<div class="settings-group-title"> <div class="settings-group-title">
<span class="settings-row-title">强约束系统</span <span class="settings-row-title">强约束系统</span
@ -1473,14 +1275,7 @@
key: 'skill_strict_terminal_enabled', key: 'skill_strict_terminal_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.skill_strict_terminal_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row inner" <label class="settings-toggle-row inner"
><span class="settings-row-title">子智能体系列工具</span ><span class="settings-row-title">子智能体系列工具</span
><input ><input
@ -1491,14 +1286,7 @@
key: 'skill_strict_sub_agent_enabled', key: 'skill_strict_sub_agent_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.skill_strict_sub_agent_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row inner" <label class="settings-toggle-row inner"
><span class="settings-row-title">run_command 前台模式</span ><span class="settings-row-title">run_command 前台模式</span
><input ><input
@ -1509,14 +1297,7 @@
key: 'skill_strict_run_command_foreground_enabled', key: 'skill_strict_run_command_foreground_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.skill_strict_run_command_foreground_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
<label class="settings-toggle-row inner" <label class="settings-toggle-row inner"
><span class="settings-row-title">run_command 后台模式</span ><span class="settings-row-title">run_command 后台模式</span
><input ><input
@ -1527,14 +1308,7 @@
key: 'skill_strict_run_command_background_enabled', key: 'skill_strict_run_command_background_enabled',
value: $event.target.checked value: $event.target.checked
}) })
" /><span class="fancy-check" aria-hidden="true" " /><FancyCheck :checked="form.skill_strict_run_command_background_enabled" /></label>
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
</div> </div>
<div class="settings-group-block" v-if="skillsCatalog.length"> <div class="settings-group-block" v-if="skillsCatalog.length">
<div class="settings-group-title"> <div class="settings-group-title">
@ -1553,16 +1327,7 @@
><input ><input
type="checkbox" type="checkbox"
:checked="form.enabled_skills.includes(skill.id)" :checked="form.enabled_skills.includes(skill.id)"
@change="personalization.toggleSkill(skill.id)" /><span @change="personalization.toggleSkill(skill.id)" /><FancyCheck :checked="form.enabled_skills.includes(skill.id)" /></label>
class="fancy-check"
aria-hidden="true"
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
</div> </div>
</div> </div>
<div class="settings-group-block" v-if="toolCategories.length"> <div class="settings-group-block" v-if="toolCategories.length">
@ -1579,16 +1344,7 @@
><input ><input
type="checkbox" type="checkbox"
:checked="form.disabled_tool_categories.includes(category.id)" :checked="form.disabled_tool_categories.includes(category.id)"
@change="toggleCategory(category.id)" /><span @change="toggleCategory(category.id)" /><FancyCheck :checked="form.disabled_tool_categories.includes(category.id)" /></label>
class="fancy-check"
aria-hidden="true"
><svg viewBox="0 0 64 64">
<path
d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
pathLength="575.0541381835938"
class="fancy-path"
></path></svg></span
></label>
</div> </div>
</div> </div>
</section> </section>
@ -2137,6 +1893,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick, onBeforeUnmount } from 'vue'; import { ref, computed, watch, onMounted, nextTick, onBeforeUnmount } from 'vue';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import FancyCheck from '@/components/common/FancyCheck.vue';
import { usePersonalizationStore } from '@/stores/personalization'; import { usePersonalizationStore } from '@/stores/personalization';
import { useResourceStore } from '@/stores/resource'; import { useResourceStore } from '@/stores/resource';
import { useUiStore } from '@/stores/ui'; import { useUiStore } from '@/stores/ui';
@ -4012,44 +3769,6 @@ const applyThemeOption = async (theme: ThemeKey) => {
pointer-events: none; pointer-events: none;
} }
.settings-toggle-row .fancy-check {
width: 28px;
height: 28px;
border-radius: 6px;
background: transparent;
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow: none;
transition: opacity 0.2s ease;
}
.settings-toggle-row .fancy-check svg {
width: 22px;
height: 22px;
overflow: visible;
}
.fancy-path {
fill: none;
stroke: var(--text-secondary);
stroke-width: 5;
stroke-linecap: round;
stroke-linejoin: round;
transition:
stroke-dasharray 0.5s ease,
stroke-dashoffset 0.5s ease,
stroke 0.2s ease;
stroke-dasharray: 241 9999999;
stroke-dashoffset: 0;
}
.settings-toggle-row input:checked + .fancy-check .fancy-path {
stroke: var(--text-secondary);
stroke-dasharray: 70.5096664428711 9999999;
stroke-dashoffset: -262.2723388671875;
}
.settings-group-block { .settings-group-block {
border-bottom: 1px solid var(--theme-control-border); border-bottom: 1px solid var(--theme-control-border);
padding: 14px 0 16px; padding: 14px 0 16px;

View File

@ -209,49 +209,6 @@
pointer-events: none; pointer-events: none;
} }
.toggle-row .fancy-check {
width: 28px;
height: 28px;
border-radius: 6px;
background: transparent;
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow: none;
transition: opacity 0.2s ease;
}
.toggle-row .fancy-check svg {
width: 22px;
height: 22px;
overflow: visible;
}
.fancy-path {
fill: none;
stroke: var(--text-secondary);
stroke-width: 5;
stroke-linecap: round;
stroke-linejoin: round;
transition:
stroke-dasharray 0.5s ease,
stroke-dashoffset 0.5s ease,
stroke 0.2s ease;
stroke-dasharray: 241 9999999;
stroke-dashoffset: 0;
}
.toggle-row input:checked + .fancy-check {
background: transparent;
box-shadow: none;
}
.toggle-row input:checked + .fancy-check .fancy-path {
stroke: var(--accent);
stroke-dasharray: 70.5096664428711 9999999;
stroke-dashoffset: -262.2723388671875;
}
.toggle-row span { .toggle-row span {
color: var(--text-primary); color: var(--text-primary);
font-weight: 500; font-weight: 500;