feat: console spacing/cards polish, create card, drop kids/jump, borderless entry
This commit is contained in:
@@ -372,8 +372,8 @@ async function coldPreviewOf(face: any): Promise<string> {
|
|||||||
for (const b of blocks) {
|
for (const b of blocks) {
|
||||||
const s = typeof b?.text === 'string' ? b.text.trim().replace(/\s+/g, ' ') : ''
|
const s = typeof b?.text === 'string' ? b.text.trim().replace(/\s+/g, ' ') : ''
|
||||||
if (!s) continue
|
if (!s) continue
|
||||||
if (b?.type === 'text') return s.slice(0, 140)
|
if (b?.type === 'text') return s.slice(0, 220)
|
||||||
if (!fallback) fallback = s.slice(0, 140)
|
if (!fallback) fallback = s.slice(0, 220)
|
||||||
}
|
}
|
||||||
return fallback
|
return fallback
|
||||||
}
|
}
|
||||||
@@ -986,6 +986,16 @@ function WorktableSection(props: any) {
|
|||||||
return cards
|
return cards
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 打开「添加项目」面板(侧栏 + 与控制室创建卡共用):默认父目录 = 当前会话工作目录 */
|
||||||
|
const openAddPanel = () => {
|
||||||
|
setAddOpen(true)
|
||||||
|
setViewOptionsOpen(false)
|
||||||
|
if (!wsFolderParent) {
|
||||||
|
const cwd = sessionScopeStore.snapshot?.cwd ?? ''
|
||||||
|
if (cwd) setWsFolderParent(cwd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 会话作用域(当前会话 + 工作目录)与后台任务:注入分栏引擎环境
|
// 会话作用域(当前会话 + 工作目录)与后台任务:注入分栏引擎环境
|
||||||
// 注意:不走 props.useSessions hook(其宿主包装在部分版本会触发 useSyncExternalStore
|
// 注意:不走 props.useSessions hook(其宿主包装在部分版本会触发 useSyncExternalStore
|
||||||
// 崩溃),改为 apply 里订阅 ctx.sessions.list 后写入模块级 store,此处直接读取。
|
// 崩溃),改为 apply 里订阅 ctx.sessions.list 后写入模块级 store,此处直接读取。
|
||||||
@@ -1046,6 +1056,7 @@ function WorktableSection(props: any) {
|
|||||||
if (previewTimer != null) { window.clearTimeout(previewTimer); previewTimer = null }
|
if (previewTimer != null) { window.clearTimeout(previewTimer); previewTimer = null }
|
||||||
sweepPreviews()
|
sweepPreviews()
|
||||||
},
|
},
|
||||||
|
onAdd: () => openAddPanel(),
|
||||||
onOpen: (id) => {
|
onOpen: (id) => {
|
||||||
if (id === CONSOLE_ID) return
|
if (id === CONSOLE_ID) return
|
||||||
const pr = projectsRef.current.projects
|
const pr = projectsRef.current.projects
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ export const zh = {
|
|||||||
'console.createBind': '新建并绑定',
|
'console.createBind': '新建并绑定',
|
||||||
'console.bindFail': '创建失败,请重试',
|
'console.bindFail': '创建失败,请重试',
|
||||||
'console.noSessions': '没有可用对话',
|
'console.noSessions': '没有可用对话',
|
||||||
|
'console.addProject': '添加项目',
|
||||||
'pane.wip': '开发中(后续版本接入)',
|
'pane.wip': '开发中(后续版本接入)',
|
||||||
'pane.explorerNoCwd': '当前会话没有工作目录',
|
'pane.explorerNoCwd': '当前会话没有工作目录',
|
||||||
'pane.openLater': '该类型暂不支持预览',
|
'pane.openLater': '该类型暂不支持预览',
|
||||||
@@ -299,6 +300,7 @@ export const en = {
|
|||||||
'console.createBind': 'Create & bind',
|
'console.createBind': 'Create & bind',
|
||||||
'console.bindFail': 'Creation failed, try again',
|
'console.bindFail': 'Creation failed, try again',
|
||||||
'console.noSessions': 'No sessions available',
|
'console.noSessions': 'No sessions available',
|
||||||
|
'console.addProject': 'Add project',
|
||||||
'pane.wip': 'Coming in a later version',
|
'pane.wip': 'Coming in a later version',
|
||||||
'pane.explorerNoCwd': 'No working directory for the current session',
|
'pane.explorerNoCwd': 'No working directory for the current session',
|
||||||
'pane.openLater': 'Preview not supported for this type',
|
'pane.openLater': 'Preview not supported for this type',
|
||||||
|
|||||||
@@ -232,6 +232,8 @@ type SplitEnv = {
|
|||||||
onAck: (id: string) => void
|
onAck: (id: string) => void
|
||||||
/** 冷会话消息预热(打开控制室时拉最近消息) */
|
/** 冷会话消息预热(打开控制室时拉最近消息) */
|
||||||
refreshPreviews: () => void
|
refreshPreviews: () => void
|
||||||
|
/** 创建卡片:打开「添加项目」流程(同侧栏 +) */
|
||||||
|
onAdd: () => void
|
||||||
getTheme: () => 'dark' | 'light' | 'system'
|
getTheme: () => 'dark' | 'light' | 'system'
|
||||||
setTheme: (th: 'dark' | 'light' | 'system') => void
|
setTheme: (th: 'dark' | 'light' | 'system') => void
|
||||||
}
|
}
|
||||||
@@ -1055,27 +1057,27 @@ function ConsolePane() {
|
|||||||
<span className="dsh-wt_consoleName">{c.name}</span>
|
<span className="dsh-wt_consoleName">{c.name}</span>
|
||||||
<span className={'dsh-wt_consoleDot dsh-wt_consoleDot-' + c.status} aria-hidden />
|
<span className={'dsh-wt_consoleDot dsh-wt_consoleDot-' + c.status} aria-hidden />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="dsh-wt_consoleDivider" aria-hidden />
|
||||||
<div className="dsh-wt_consoleStatusRow">
|
<div className="dsh-wt_consoleStatusRow">
|
||||||
<span className={'dsh-wt_consoleStatus dsh-wt_consoleStatus-' + c.status}>{statusLabel[c.status]}</span>
|
<span className={'dsh-wt_consoleStatus dsh-wt_consoleStatus-' + c.status}>{statusLabel[c.status]}</span>
|
||||||
{c.runtimeMs != null && <span className="dsh-wt_consoleRuntime">⏱ {fmtDur(c.runtimeMs)}</span>}
|
{c.runtimeMs != null && <span className="dsh-wt_consoleRuntime">⏱ {fmtDur(c.runtimeMs)}</span>}
|
||||||
</div>
|
</div>
|
||||||
<div className="dsh-wt_consoleBadges">
|
|
||||||
<span className="dsh-wt_consoleBadge">{T('console.kids')} {c.kids}</span>
|
|
||||||
</div>
|
|
||||||
<div className={'dsh-wt_consolePreview' + (c.preview ? '' : ' dsh-wt_consolePreviewNone')} title={c.preview}>
|
<div className={'dsh-wt_consolePreview' + (c.preview ? '' : ' dsh-wt_consolePreviewNone')} title={c.preview}>
|
||||||
{c.preview || (c.bound ? T('console.noPreview') : T('console.unboundShort'))}
|
{c.preview || (c.bound ? T('console.noPreview') : T('console.unboundShort'))}
|
||||||
</div>
|
</div>
|
||||||
{c.bound && !c.self && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="dsh-wt_consoleJump"
|
|
||||||
title={T('console.jump')}
|
|
||||||
aria-label={T('console.jump')}
|
|
||||||
onClick={(e) => { e.stopPropagation(); env?.onJump(c.id) }}
|
|
||||||
>💬</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{/* 创建卡片:永远最后一位;点击 = 侧栏工作台「添加项目」同款流程 */}
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
className="dsh-wt_consoleCard dsh-wt_consoleAdd"
|
||||||
|
title={T('console.addProject')}
|
||||||
|
onClick={() => env?.onAdd?.()}
|
||||||
|
>
|
||||||
|
<span className="dsh-wt_consoleAddPlus" aria-hidden>+</span>
|
||||||
|
<span className="dsh-wt_consoleAddLabel">{T('console.addProject')}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{cards.length === 0 && <div className="dsh-wt_consoleEmpty">{T('console.empty')}</div>}
|
{cards.length === 0 && <div className="dsh-wt_consoleEmpty">{T('console.empty')}</div>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -390,26 +390,25 @@ export const css = xtermCss + '\n' + [
|
|||||||
'.dsh-wt_consoleThemeBtn{flex:none;padding:3px 9px;border:none;border-radius:999px;background:transparent;color:var(--wt-text3);font:inherit;font-size:12px;line-height:18px;cursor:pointer;opacity:.85}',
|
'.dsh-wt_consoleThemeBtn{flex:none;padding:3px 9px;border:none;border-radius:999px;background:transparent;color:var(--wt-text3);font:inherit;font-size:12px;line-height:18px;cursor:pointer;opacity:.85}',
|
||||||
'.dsh-wt_consoleThemeBtn:hover{opacity:1;background:var(--wt-chip)}',
|
'.dsh-wt_consoleThemeBtn:hover{opacity:1;background:var(--wt-chip)}',
|
||||||
'.dsh-wt_consoleThemeBtnOn{background:var(--wt-chip);color:var(--wt-text);opacity:1}',
|
'.dsh-wt_consoleThemeBtnOn{background:var(--wt-chip);color:var(--wt-text);opacity:1}',
|
||||||
'.dsh-wt_consoleGrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px;align-content:start;max-width:720px;margin:0 auto}',
|
'.dsh-wt_consoleGrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:64px;align-content:start;margin-top:clamp(32px,9vh,110px)}',
|
||||||
'.dsh-wt_consoleCard{position:relative;display:flex;flex-direction:column;gap:10px;aspect-ratio:1/1;min-height:150px;padding:16px;background:var(--wt-card);border:1px solid var(--wt-border);border-radius:14px;cursor:pointer;transition:transform .12s ease,border-color .12s ease,box-shadow .12s ease;overflow:hidden}',
|
'.dsh-wt_consoleCard{position:relative;display:flex;flex-direction:column;gap:12px;aspect-ratio:1/1;min-height:170px;padding:19px;background:var(--wt-card);border:1px solid var(--wt-border);border-radius:14px;cursor:pointer;transition:transform .12s ease,border-color .12s ease,box-shadow .12s ease;overflow:hidden}',
|
||||||
'.dsh-wt_consoleCard:hover{transform:translateY(-2px);border-color:var(--wt-borderHover);box-shadow:var(--wt-shadow)}',
|
'.dsh-wt_consoleCard:hover{transform:translateY(-2px);border-color:var(--wt-borderHover);box-shadow:var(--wt-shadow)}',
|
||||||
'.dsh-wt_consoleCardSelf{cursor:default;opacity:.97}',
|
'.dsh-wt_consoleCardSelf{cursor:default;opacity:.97}',
|
||||||
'.dsh-wt_consoleCardHead{display:flex;align-items:center;gap:9px;min-width:0}',
|
'.dsh-wt_consoleCardHead{display:flex;align-items:center;gap:10px;min-width:0}',
|
||||||
'.dsh-wt_consoleIcon{flex:none;font-size:24px;line-height:1}',
|
'.dsh-wt_consoleIcon{flex:none;font-size:28px;line-height:1}',
|
||||||
'.dsh-wt_consoleName{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14.5px;font-weight:700;line-height:22px;color:var(--wt-text)}',
|
'.dsh-wt_consoleName{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:17.5px;font-weight:700;line-height:26px;color:var(--wt-text)}',
|
||||||
'.dsh-wt_consoleDot{flex:none;width:9px;height:9px;border-radius:50%;background:var(--wt-text3)}',
|
'.dsh-wt_consoleDivider{flex:none;height:1px;background:var(--wt-border)}',
|
||||||
|
'.dsh-wt_consoleDot{flex:none;width:10px;height:10px;border-radius:50%;background:var(--wt-text3)}',
|
||||||
'.dsh-wt_consoleDot-busy{background:var(--dsw-alias-state-accent-primary,#4f8ef7);box-shadow:0 0 0 4px rgba(79,142,247,.16)}',
|
'.dsh-wt_consoleDot-busy{background:var(--dsw-alias-state-accent-primary,#4f8ef7);box-shadow:0 0 0 4px rgba(79,142,247,.16)}',
|
||||||
'.dsh-wt_consoleDot-need{background:var(--dsw-alias-state-warning,#d29922);box-shadow:0 0 0 4px rgba(210,153,34,.16)}',
|
'.dsh-wt_consoleDot-need{background:var(--dsw-alias-state-warning,#d29922);box-shadow:0 0 0 4px rgba(210,153,34,.16)}',
|
||||||
'.dsh-wt_consoleDot-done{background:var(--dsw-alias-state-success,#3fb950);box-shadow:0 0 0 4px rgba(63,185,80,.16)}',
|
'.dsh-wt_consoleDot-done{background:var(--dsw-alias-state-success,#3fb950);box-shadow:0 0 0 4px rgba(63,185,80,.16)}',
|
||||||
'.dsh-wt_consoleStatusRow{display:flex;align-items:baseline;gap:8px;min-width:0}',
|
'.dsh-wt_consoleStatusRow{display:flex;align-items:baseline;gap:9px;min-width:0}',
|
||||||
'.dsh-wt_consoleStatus{flex:none;font-size:17px;font-weight:700;line-height:24px;color:var(--wt-text2)}',
|
'.dsh-wt_consoleStatus{flex:none;font-size:20px;font-weight:700;line-height:28px;color:var(--wt-text2)}',
|
||||||
'.dsh-wt_consoleStatus-busy{color:var(--dsw-alias-state-accent-primary,#4f8ef7)}',
|
'.dsh-wt_consoleStatus-busy{color:var(--dsw-alias-state-accent-primary,#4f8ef7)}',
|
||||||
'.dsh-wt_consoleStatus-need{color:var(--dsw-alias-state-warning,#d29922)}',
|
'.dsh-wt_consoleStatus-need{color:var(--dsw-alias-state-warning,#d29922)}',
|
||||||
'.dsh-wt_consoleStatus-done{color:var(--dsw-alias-state-success,#3fb950)}',
|
'.dsh-wt_consoleStatus-done{color:var(--dsw-alias-state-success,#3fb950)}',
|
||||||
'.dsh-wt_consoleRuntime{flex:none;font-size:13px;font-weight:600;line-height:20px;color:var(--wt-text2);font-variant-numeric:tabular-nums}',
|
'.dsh-wt_consoleRuntime{flex:none;font-size:15px;font-weight:600;line-height:24px;color:var(--wt-text2);font-variant-numeric:tabular-nums}',
|
||||||
'.dsh-wt_consoleBadges{display:flex;align-items:center;gap:6px;flex-wrap:wrap}',
|
'.dsh-wt_consolePreview{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden;font-size:11px;line-height:16px;color:var(--wt-text2);word-break:break-word}',
|
||||||
'.dsh-wt_consoleBadge{flex:none;padding:2px 9px;border-radius:999px;font-size:12px;font-weight:600;line-height:18px;color:var(--wt-text2);background:var(--wt-chip)}',
|
|
||||||
'.dsh-wt_consolePreview{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:12.5px;line-height:18px;color:var(--wt-text2);word-break:break-word}',
|
|
||||||
'.dsh-wt_consolePreviewNone{color:var(--wt-text3);font-style:italic;-webkit-line-clamp:1}',
|
'.dsh-wt_consolePreviewNone{color:var(--wt-text3);font-style:italic;-webkit-line-clamp:1}',
|
||||||
// 三色光效:整卡霓虹描边光晕(像侧栏双圆点的发光质感)——完成=绿、待决=黄;工作=蓝色描边顺时针旋转
|
// 三色光效:整卡霓虹描边光晕(像侧栏双圆点的发光质感)——完成=绿、待决=黄;工作=蓝色描边顺时针旋转
|
||||||
'.dsh-wt_consoleCard-glowDone{border-color:rgba(63,185,80,.9);box-shadow:0 0 8px rgba(63,185,80,.5),0 0 26px rgba(63,185,80,.3),inset 0 0 16px rgba(63,185,80,.07)}',
|
'.dsh-wt_consoleCard-glowDone{border-color:rgba(63,185,80,.9);box-shadow:0 0 8px rgba(63,185,80,.5),0 0 26px rgba(63,185,80,.3),inset 0 0 16px rgba(63,185,80,.07)}',
|
||||||
@@ -418,14 +417,18 @@ export const css = xtermCss + '\n' + [
|
|||||||
'.dsh-wt_consoleCard-busy{box-shadow:0 0 14px rgba(79,142,247,.28)}',
|
'.dsh-wt_consoleCard-busy{box-shadow:0 0 14px rgba(79,142,247,.28)}',
|
||||||
'.dsh-wt_consoleCard-busy::before{content:"";position:absolute;inset:-2px;border-radius:16px;padding:2px;background:conic-gradient(from var(--consoleAngle),transparent 0deg,rgba(79,142,247,0) 20deg,#5aa0ff 80deg,rgba(79,142,247,0) 140deg,transparent 200deg);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;animation:consoleAngleSpin 1.6s linear infinite;pointer-events:none}',
|
'.dsh-wt_consoleCard-busy::before{content:"";position:absolute;inset:-2px;border-radius:16px;padding:2px;background:conic-gradient(from var(--consoleAngle),transparent 0deg,rgba(79,142,247,0) 20deg,#5aa0ff 80deg,rgba(79,142,247,0) 140deg,transparent 200deg);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);mask-composite:exclude;animation:consoleAngleSpin 1.6s linear infinite;pointer-events:none}',
|
||||||
'@keyframes consoleAngleSpin{to{--consoleAngle:360deg}}',
|
'@keyframes consoleAngleSpin{to{--consoleAngle:360deg}}',
|
||||||
'.dsh-wt_consoleJump{position:absolute;top:12px;right:12px;width:24px;height:24px;padding:0;border:none;border-radius:7px;background:transparent;color:var(--wt-text3);font-size:13px;line-height:1;cursor:pointer;opacity:0;transition:opacity .12s ease}',
|
|
||||||
'.dsh-wt_consoleCard:hover .dsh-wt_consoleJump{opacity:1}',
|
|
||||||
'.dsh-wt_consoleJump:hover{color:var(--dsw-alias-state-accent-primary,#4f8ef7);background:var(--wt-chip)}',
|
|
||||||
'.dsh-wt_consoleEmpty{padding:40px 0;text-align:center;font-size:12px;color:var(--wt-text3)}',
|
'.dsh-wt_consoleEmpty{padding:40px 0;text-align:center;font-size:12px;color:var(--wt-text3)}',
|
||||||
// 控制室入口卡:统筹主程序的差异化(渐变底 + 青色描边 + 微光,克制不喧宾夺主)
|
// 创建卡片:虚线 + 居中加号,永远最后一位
|
||||||
'.dsh-wt_projects .dsh-wt_consoleEntry{background:linear-gradient(135deg,rgba(79,142,247,.14),rgba(139,92,246,.10));border-color:rgba(79,142,247,.4);box-shadow:0 0 12px rgba(79,142,247,.14)}',
|
'.dsh-wt_consoleAdd{justify-content:center;align-items:center;gap:8px;background:transparent;border:1.5px dashed var(--wt-borderHover)}',
|
||||||
'.dsh-wt_projects .dsh-wt_consoleEntry:hover{background:linear-gradient(135deg,rgba(79,142,247,.2),rgba(139,92,246,.14));border-color:rgba(79,142,247,.6);box-shadow:0 0 16px rgba(79,142,247,.22)}',
|
'.dsh-wt_consoleAdd:hover{border-color:var(--dsw-alias-state-accent-primary,#4f8ef7);background:var(--wt-chip)}',
|
||||||
'.dsh-wt_projects .dsh-wt_consoleEntry[data-on=true]{border-color:rgba(79,142,247,.7);box-shadow:0 0 16px rgba(79,142,247,.28)}',
|
'.dsh-wt_consoleAddPlus{font-size:30px;line-height:1;color:var(--wt-text2);font-weight:400}',
|
||||||
|
'.dsh-wt_consoleAdd:hover .dsh-wt_consoleAddPlus{color:var(--dsw-alias-state-accent-primary,#4f8ef7)}',
|
||||||
|
'.dsh-wt_consoleAddLabel{font-size:13px;font-weight:600;color:var(--wt-text2)}',
|
||||||
|
'.dsh-wt_consoleAdd:hover .dsh-wt_consoleAddLabel{color:var(--dsw-alias-state-accent-primary,#4f8ef7)}',
|
||||||
|
// 控制室入口卡:统筹主程序的差异化(渐变底 + 微光;无描边,颜色更亮更饱和)
|
||||||
|
'.dsh-wt_projects .dsh-wt_consoleEntry{background:linear-gradient(135deg,rgba(109,164,255,.30),rgba(167,130,255,.22));border-color:transparent;box-shadow:0 0 14px rgba(96,150,255,.22)}',
|
||||||
|
'.dsh-wt_projects .dsh-wt_consoleEntry:hover{background:linear-gradient(135deg,rgba(109,164,255,.42),rgba(167,130,255,.32));box-shadow:0 0 18px rgba(96,150,255,.32)}',
|
||||||
|
'.dsh-wt_projects .dsh-wt_consoleEntry[data-on=true]{background:linear-gradient(135deg,rgba(109,164,255,.38),rgba(167,130,255,.28));box-shadow:0 0 18px rgba(96,150,255,.34)}',
|
||||||
'.dsh-wt_projects .dsh-wt_consoleEntry .dsh-wt_layoutIcon{font-size:15px}',
|
'.dsh-wt_projects .dsh-wt_consoleEntry .dsh-wt_layoutIcon{font-size:15px}',
|
||||||
'.dsh-wt_projects .dsh-wt_consoleEntry .dsh-wt_layoutName{font-weight:600;color:var(--dsw-alias-label-primary,#e6e8eb)}',
|
'.dsh-wt_projects .dsh-wt_consoleEntry .dsh-wt_layoutName{font-weight:600;color:var(--dsw-alias-label-primary,#e6e8eb)}',
|
||||||
// 控制室强制绑定弹窗:左加入现有 / 右新建对话
|
// 控制室强制绑定弹窗:左加入现有 / 右新建对话
|
||||||
|
|||||||
@@ -1231,3 +1231,21 @@
|
|||||||
- 验证:probe-batch16 healTabs=1、healType='console' ✓,全流程 ✓;functional-diag
|
- 验证:probe-batch16 healTabs=1、healType='console' ✓,全流程 ✓;functional-diag
|
||||||
全 20 STEP ERROR_COUNT: 0。
|
全 20 STEP ERROR_COUNT: 0。
|
||||||
- 备注:纯客户端改动,F5 即生效;用户 F5 后坏存档自动修复,点「控制室」卡片即恢复面板。
|
- 备注:纯客户端改动,F5 即生效;用户 F5 后坏存档自动修复,点「控制室」卡片即恢复面板。
|
||||||
|
|
||||||
|
## 补记(控制室第三轮打磨:下沉居中 + 4 倍间距 + 1.2 倍卡片 + 创建卡 + 去子代理/💬 + 入口无描边)
|
||||||
|
|
||||||
|
- 用户反馈:① 卡片太靠上 → 网格下沉(margin-top clamp(32px,9vh,110px),接近画面中部);
|
||||||
|
② 卡间距太小 → gap 16→64px(4 倍);③ 卡片整体放大 1.2 倍(padding 19/图标 28/
|
||||||
|
名字 17.5/状态 20/时长 15);④ 删掉右上角隐藏的 💬 跳转按钮(无意义);⑤ 网格最后
|
||||||
|
一位永远是一张「创建卡片」(虚线 + 居中加号),点击 = 侧栏工作台「添加项目」同款流程
|
||||||
|
(openAddPanel 共用:setAddOpen + 默认父目录取当前会话 cwd);⑥ 侧栏控制室入口卡去掉
|
||||||
|
描边(border transparent),渐变颜色提亮提饱和(rgba(109,164,255,.30)→
|
||||||
|
rgba(167,130,255,.22)),保留微光;⑦ 子代理徽章全删(都是 0 无信息);⑧ 卡片名字下方
|
||||||
|
加横向分隔线(标题/状态/预览层次分明);⑨ 预览字改小(11px)行数提到 4 行,抓取切
|
||||||
|
220 字符;⑩ 名字字号变大且**所有卡片共用类名**——以后新建的项目卡片自动同字号。
|
||||||
|
- 验证(probe-batch16 更新):gridGap 64px / gridMarginTop 72px ✓、nameFont 17.5px /
|
||||||
|
previewFont 11px / statusFont 20px ✓、dividerExists ✓、kidsGone/jumpGone ✓、
|
||||||
|
addCardLast(+)且点击开添加面板(addPopOpened)✓、入口 border rgba(0,0,0,0) +
|
||||||
|
渐变 ✓、真实运行会话 busy 旋转光弧动效生效 ✓;全流程 + 主题 ✓;functional-diag
|
||||||
|
全 20 STEP ERROR_COUNT: 0。
|
||||||
|
- 备注:纯客户端改动,F5 即生效。
|
||||||
|
|||||||
@@ -135,16 +135,31 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|||||||
out.gridFound = !!grid;
|
out.gridFound = !!grid;
|
||||||
if (grid) {
|
if (grid) {
|
||||||
out.gridCols = getComputedStyle(grid).gridTemplateColumns.split(' ').length;
|
out.gridCols = getComputedStyle(grid).gridTemplateColumns.split(' ').length;
|
||||||
|
out.gridGap = getComputedStyle(grid).columnGap;
|
||||||
|
out.gridMarginTop = getComputedStyle(grid).marginTop;
|
||||||
var cards = grid.querySelectorAll('.dsh-wt_consoleCard');
|
var cards = grid.querySelectorAll('.dsh-wt_consoleCard');
|
||||||
out.cardCount = cards.length;
|
out.cardCount = cards.length;
|
||||||
var c0 = cards[0];
|
var c0 = cards[0];
|
||||||
out.firstCardSelf = !!(c0 && c0.classList.contains('dsh-wt_consoleCardSelf'));
|
out.firstCardSelf = !!(c0 && c0.classList.contains('dsh-wt_consoleCardSelf'));
|
||||||
out.firstCardIcon = c0 ? c0.querySelector('.dsh-wt_consoleIcon').textContent : null;
|
out.firstCardIcon = c0 ? c0.querySelector('.dsh-wt_consoleIcon').textContent : null;
|
||||||
out.firstCardDot = c0 && c0.querySelector('.dsh-wt_consoleDot') ? c0.querySelector('.dsh-wt_consoleDot').className.replace('dsh-wt_consoleDot','').trim() : null;
|
out.firstCardDot = c0 && c0.querySelector('.dsh-wt_consoleDot') ? c0.querySelector('.dsh-wt_consoleDot').className.replace('dsh-wt_consoleDot','').trim() : null;
|
||||||
out.firstCardBadges = c0 ? c0.querySelectorAll('.dsh-wt_consoleBadge').length : 0;
|
out.nameFont = c0 && c0.querySelector('.dsh-wt_consoleName') ? getComputedStyle(c0.querySelector('.dsh-wt_consoleName')).fontSize : null;
|
||||||
|
out.dividerExists = !!(c0 && c0.querySelector('.dsh-wt_consoleDivider'));
|
||||||
|
out.kidsGone = !(c0 && c0.querySelector('.dsh-wt_consoleBadge'));
|
||||||
|
out.jumpGone = !(c0 && c0.querySelector('.dsh-wt_consoleJump'));
|
||||||
|
out.previewFont = c0 && c0.querySelector('.dsh-wt_consolePreview') ? getComputedStyle(c0.querySelector('.dsh-wt_consolePreview')).fontSize : null;
|
||||||
out.firstCardHasPreview = !!(c0 && c0.querySelector('.dsh-wt_consolePreview'));
|
out.firstCardHasPreview = !!(c0 && c0.querySelector('.dsh-wt_consolePreview'));
|
||||||
out.anyLayoutCard = [].slice.call(cards).some(function(c){ return (c.textContent||'').indexOf('绑定测试') >= 0; });
|
out.anyLayoutCard = [].slice.call(cards).some(function(c){ return (c.textContent||'').indexOf('绑定测试') >= 0; });
|
||||||
out.layoutCardHasJump = [].slice.call(cards).some(function(c){ return (c.textContent||'').indexOf('绑定测试') >= 0 && !!c.querySelector('.dsh-wt_consoleJump'); });
|
// 创建卡片永远最后一位;点击打开「添加项目」面板
|
||||||
|
var addCard = grid.lastElementChild;
|
||||||
|
out.addCardLast = !!(addCard && addCard.classList.contains('dsh-wt_consoleAdd'));
|
||||||
|
out.addPlus = addCard && addCard.querySelector('.dsh-wt_consoleAddPlus') ? addCard.querySelector('.dsh-wt_consoleAddPlus').textContent : null;
|
||||||
|
if (addCard) { addCard.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||||
|
await sleep(500);
|
||||||
|
out.addPopOpened = !!vis('.dsh-wt_add');
|
||||||
|
var bd = vis('.dsh-wt_popBackdrop');
|
||||||
|
if (bd) { bd.dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true})); }
|
||||||
|
await sleep(300);
|
||||||
// 新版 UI:正方形比例、大字号状态、光效 CSS 接线(注入类验证,不依赖真实会话状态)
|
// 新版 UI:正方形比例、大字号状态、光效 CSS 接线(注入类验证,不依赖真实会话状态)
|
||||||
var cardEl = c0;
|
var cardEl = c0;
|
||||||
if (cardEl) {
|
if (cardEl) {
|
||||||
@@ -226,13 +241,8 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|||||||
out.bindPopNotShown = !vis('.dsh-wt_consoleBindPop');
|
out.bindPopNotShown = !vis('.dsh-wt_consoleBindPop');
|
||||||
var grid = vis('.dsh-wt_consoleGrid');
|
var grid = vis('.dsh-wt_consoleGrid');
|
||||||
var lc = grid && [].slice.call(grid.querySelectorAll('.dsh-wt_consoleCard')).find(function(c){ return (c.textContent||'').indexOf('绑定测试') >= 0; });
|
var lc = grid && [].slice.call(grid.querySelectorAll('.dsh-wt_consoleCard')).find(function(c){ return (c.textContent||'').indexOf('绑定测试') >= 0; });
|
||||||
out.layoutJumpBtn = !!(lc && lc.querySelector('.dsh-wt_consoleJump'));
|
out.jumpBtnGone = !(lc && lc.querySelector('.dsh-wt_consoleJump'));
|
||||||
out.layoutCardStatus = lc && lc.querySelector('.dsh-wt_consoleDot') ? lc.querySelector('.dsh-wt_consoleDot').className.replace('dsh-wt_consoleDot','').trim() : null;
|
out.layoutCardStatus = lc && lc.querySelector('.dsh-wt_consoleDot') ? lc.querySelector('.dsh-wt_consoleDot').className.replace('dsh-wt_consoleDot','').trim() : null;
|
||||||
if (lc && lc.querySelector('.dsh-wt_consoleJump')) {
|
|
||||||
lc.querySelector('.dsh-wt_consoleJump').dispatchEvent(new MouseEvent('click', {bubbles:true, cancelable:true}));
|
|
||||||
await sleep(700);
|
|
||||||
out.specAfterJump = st.active && st.spec ? st.spec.id : null;
|
|
||||||
}
|
|
||||||
st.close(); await sleep(300);
|
st.close(); await sleep(300);
|
||||||
} catch (e) { out.err = String(e && e.stack || e); }
|
} catch (e) { out.err = String(e && e.stack || e); }
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@@ -84,12 +84,11 @@ node --check lib/index.js
|
|||||||
建空会话 sessions.create 后自动绑定并打开控制室)。绑定也走 projects.v1.bindings。
|
建空会话 sessions.create 后自动绑定并打开控制室)。绑定也走 projects.v1.bindings。
|
||||||
- 控制室面板(split.tsx ConsolePane):卡片网格每行 3 张、超出换行;每卡 = 图标/名称/
|
- 控制室面板(split.tsx ConsolePane):卡片网格每行 3 张、超出换行;每卡 = 图标/名称/
|
||||||
三态圆点(need>done>busy>idle,不过滤 ack,永远显示事实状态)/运行时长(后台任务
|
三态圆点(need>done>busy>idle,不过滤 ack,永远显示事实状态)/运行时长(后台任务
|
||||||
JobView.startedAt 或会话面 turnTimings 未结束轮次)/子代理数(byId.parentId +
|
JobView.startedAt 或会话面 turnTimings 未结束轮次)/最近消息预览(会话面快照 nodes
|
||||||
subagentsByParent 双通道计数)/最近消息预览(会话面快照 nodes 末条文本,纯读内存
|
末条文本,纯读内存零 Token)。数据组装 = index.tsx getConsoleCards(env.console 注入),
|
||||||
零 Token)。数据组装 = index.tsx getConsoleCards(env.console 注入),刷新走
|
刷新走 consoleListeners(项目/会话快照变化推送)+ 面板每秒 tick。
|
||||||
consoleListeners(项目/会话快照变化推送)+ 面板每秒 tick。
|
- 卡片动作:点卡片 = 打开该项目(openSplit 或入驻项目切绑定对话);工作台自己的卡片
|
||||||
- 卡片动作:点卡片 = 打开该项目(openSplit 或入驻项目切绑定对话);💬 = 跳绑定对话
|
点击无操作。💬 跳转按钮已删除(用户定案无意义)。
|
||||||
(markPluginSessionOpen 豁免联动,控制室保持打开);工作台自己的卡片点击无操作。
|
|
||||||
- 主题:面板三选一开关(图标按钮 🌙/☀️/🖥️,title/aria 保留文字;存 view.v1 consoleTheme);
|
- 主题:面板三选一开关(图标按钮 🌙/☀️/🖥️,title/aria 保留文字;存 view.v1 consoleTheme);
|
||||||
system 读宿主 html 的 color-scheme(DSH 深色/白色/跟随系统设置都会反映到它)+
|
system 读宿主 html 的 color-scheme(DSH 深色/白色/跟随系统设置都会反映到它)+
|
||||||
prefers-color-scheme 兜底;落成 .dsh-wt_console[data-wt-theme=dark|light] 作用域变量
|
prefers-color-scheme 兜底;落成 .dsh-wt_console[data-wt-theme=dark|light] 作用域变量
|
||||||
@@ -104,8 +103,10 @@ node --check lib/index.js
|
|||||||
「控制室」(console.name/console.title locale,工作台的控制室)。
|
「控制室」(console.name/console.title locale,工作台的控制室)。
|
||||||
- 控制室标签不可关:PaneBody 对 content.type==='console' 的标签 locked(不渲染 ✕、
|
- 控制室标签不可关:PaneBody 对 content.type==='console' 的标签 locked(不渲染 ✕、
|
||||||
禁拖拽)——关掉会退化成窗格选择器,不可逆。
|
禁拖拽)——关掉会退化成窗格选择器,不可逆。
|
||||||
- 布局尺度:网格 max-width 720px 居中、gap 16px、面板 padding 22px;卡片 1:1(实测
|
- 布局尺度:网格 gap 64px(4 倍间距)、margin-top clamp(32px,9vh,110px) 下沉居中;
|
||||||
~229px 宽),保持留白。
|
卡片 1:1 整体 1.2 倍(名字 17.5px/状态 20px/预览 11px 四行截断);标题下横向分隔线;
|
||||||
|
无子代理徽章、无 💬 跳转按钮(已删);网格最后一位恒为「创建卡片」(虚线+),点击 =
|
||||||
|
侧栏「添加项目」同款 openAddPanel 流程;入口卡无描边(透明 border + 提亮渐变 + 微光)。
|
||||||
- 冷会话消息预览(方案 A):binding() 对冷会话不载入文本;预热走 face.history({maxMessages:2})
|
- 冷会话消息预览(方案 A):binding() 对冷会话不载入文本;预热走 face.history({maxMessages:2})
|
||||||
(运行期内建方法、非公开接口,只读无副作用)尾部扫 user/message 与 assistant/message 的
|
(运行期内建方法、非公开接口,只读无副作用)尾部扫 user/message 与 assistant/message 的
|
||||||
text 块 → previewCache;sweepPreviews 在打开控制室时 + 控制室开着且会话快照变化防抖 6s
|
text 块 → previewCache;sweepPreviews 在打开控制室时 + 控制室开着且会话快照变化防抖 6s
|
||||||
|
|||||||
Reference in New Issue
Block a user