- SidebarPrefs 新增 tabsEnabled / viewersEnabled 开放 map(缺省 = 启用), PrefsSchema 用 z.dict 校验,旧文档零迁移 - TabDescriptor/FileViewerDescriptor 新增声明式设置面:viewer 补 title/icon, 两者补 settings.toggles(子代理声明 autoOpenSubagent、终端声明 agentTerminalTools) - 服务新增 isTabEnabled/isViewerEnabled;openTab 拒绝禁用类型、matchFileViewer 跳过禁用 viewer - SideCardSection 重写为注册表驱动清单:侧边栏内容(图标+类型id+开关+嵌套开关) + 文件预览(图标+标题+扩展名+开关),开关持久化 + 乐观提交回滚 - 消费点 gating:+ 菜单过滤、子代理自动展开、agent 终端 reconcile、 产出文件拦截(editor 关闭时回落默认行)、新会话 explorer 预置 - 内置 viewer 补 6 个手绘 outline 图标;store 快照携带 prefs 使开关变更即时生效 - 测试:service gating / builtins 声明 / parsePrefs map 校验 / schema 断言 / 新增 SideCardSection renderToString 规格 - 文档:README 设置小节、AGENTS.md 描述符与服务方法、新增设计文档;版本 0.5.0
89 lines
3.2 KiB
TypeScript
89 lines
3.2 KiB
TypeScript
/**
|
|
* Serializable configuration and defaults for the sidebar host half. Loader
|
|
* schema validation normally fills defaults; {@link resolveSidebarConfig}
|
|
* applies the same defaults for direct callers that bypass the Loader.
|
|
* @module dsh-better-sidebar/config
|
|
*/
|
|
|
|
import z from 'schemastery'
|
|
import {
|
|
SIDEBAR_PREFS_DEFAULTS,
|
|
SIDEBAR_PREFS_NS,
|
|
WIDTH_PERCENT_DEFAULT,
|
|
WIDTH_PERCENT_MAX,
|
|
WIDTH_PERCENT_MIN,
|
|
type SidebarPrefs,
|
|
} from './prefs-shared.ts'
|
|
|
|
export {
|
|
SIDEBAR_PREFS_DEFAULTS,
|
|
SIDEBAR_PREFS_NS,
|
|
WIDTH_PERCENT_DEFAULT,
|
|
WIDTH_PERCENT_MAX,
|
|
WIDTH_PERCENT_MIN,
|
|
type SidebarPrefs,
|
|
} from './prefs-shared.ts'
|
|
|
|
/** Tunable sidebar host limits (every field optional; defaults fill in). */
|
|
export interface SidebarConfig {
|
|
/** Read cap of one text file (bytes); larger files return truncated. */
|
|
readLimit?: number
|
|
/** Media route cap (bytes); larger binaries are refused. */
|
|
mediaLimit?: number
|
|
/** Explorer row bound of one level. */
|
|
listLimit?: number
|
|
/** Terminals per session. */
|
|
terminalsPerSession?: number
|
|
/** How long a disconnected terminal process survives awaiting a reconnect. */
|
|
reconnectGraceMs?: number
|
|
}
|
|
|
|
/** Schemastery schema for the plugin configuration. */
|
|
export const Config: z<SidebarConfig> = z.object({
|
|
readLimit: z.number().step(1).min(1).default(512 * 1024),
|
|
mediaLimit: z.number().step(1).min(1).default(20 * 1024 * 1024),
|
|
listLimit: z.number().step(1).min(1).default(1000),
|
|
terminalsPerSession: z.number().step(1).min(1).default(3),
|
|
reconnectGraceMs: z.number().step(1).min(0).default(30_000),
|
|
})
|
|
|
|
/** Fully defaulted sidebar host settings. */
|
|
export interface ResolvedSidebarConfig {
|
|
readLimit: number
|
|
mediaLimit: number
|
|
listLimit: number
|
|
terminalsPerSession: number
|
|
reconnectGraceMs: number
|
|
}
|
|
|
|
/**
|
|
* Apply direct-call defaults after Loader schema validation has normally run.
|
|
*
|
|
* @param config - Deployment-provided sidebar host settings.
|
|
* @returns Complete settings consumed by the host half.
|
|
*/
|
|
export function resolveSidebarConfig(config: SidebarConfig | undefined): ResolvedSidebarConfig {
|
|
return {
|
|
readLimit: config?.readLimit ?? 512 * 1024,
|
|
mediaLimit: config?.mediaLimit ?? 20 * 1024 * 1024,
|
|
listLimit: config?.listLimit ?? 1000,
|
|
terminalsPerSession: config?.terminalsPerSession ?? 3,
|
|
reconnectGraceMs: config?.reconnectGraceMs ?? 30_000,
|
|
}
|
|
}
|
|
|
|
// ── User-facing "Side card" preferences ─────────────────────────────────────
|
|
|
|
/** Schemastery schema for the user-facing preferences (validated by the settings service). */
|
|
export const PrefsSchema: z<SidebarPrefs> = z.object({
|
|
openByDefault: z.boolean().default(true),
|
|
defaultWidthPercent: z.number().step(1).min(WIDTH_PERCENT_MIN).max(WIDTH_PERCENT_MAX).default(WIDTH_PERCENT_DEFAULT),
|
|
autoOpenSubagent: z.boolean().default(true),
|
|
agentTerminalTools: z.boolean().default(false),
|
|
// Per-feature enable switches are OPEN maps (any tab/viewer id, built-in or
|
|
// external): an absent key means enabled, so old documents resolve to {}
|
|
// (everything on) with no migration. Non-boolean values fail validation.
|
|
tabsEnabled: z.dict(z.boolean()).default({}),
|
|
viewersEnabled: z.dict(z.boolean()).default({}),
|
|
})
|