@takazudo/app-defaults
Single source of truth for the zudotext app configuration schema, default values, and validation. Every consumer (Tauri app, scaffold tool, settings UI) imports types and defaults from this package.
Main Exports
// Types
import type {
AppSettings,
AppInstanceConfig,
FramesetTree,
HeaderLeftPin,
PinTemplate,
QuickAction,
QuickActionStep,
PinProviderPropsByProviderId,
DeviceOverride,
SyncSettings,
VimSettings,
ColorMode, // "system" | "light" | "dark" — general.colorMode (epic #5893)
} from "@takazudo/app-defaults";
// Color types re-exported from @takazudo/color-themes — see that package's docs
import type { ColorStructure, ColorSettings, ColorScheme, RampRef, Ramps, SemanticKey } from "@takazudo/color-themes";
// Default values
import {
defaultSettings,
defaultEditorSettings,
defaultVimSettings,
defaultShortcuts,
defaultLayoutSettings,
defaultGeneralSettings,
defaultColorStructure,
defaultResolvedColors,
defaultSyncSettings,
defaultActiveDraft,
defaultDraftCount,
defaultHeaderLeftPins,
defaultFramesetTree,
defaultDocCloudSettings,
defaultDirectoryViewSettings,
VIMRC_MAX_LENGTH,
COLOR_MODES, // readonly ["system", "light", "dark"] — the colorMode option list
} from "@takazudo/app-defaults";
// Validation
import { validateSettings } from "@takazudo/app-defaults";
// Toolbar surfaces (#6566, epic #6545 topic 8)
import type { ToolbarSurfaceId, ToolbarSurfaceItem, ToolbarSurfaceDef } from "@takazudo/app-defaults";
import {
TOOLBAR_SURFACES,
HEADER_ACTIONS_SURFACE_BY_PROVIDER,
isToolbarItemVisible,
withToolbarItemVisible,
defaultToolbarSettings,
} from "@takazudo/app-defaults";AppSettings Type
The AppSettings interface defines the full configuration shape stored in .zudotext.settings.json:
interface AppSettings {
general: {
colorScheme: string;
colorMode: ColorMode; // "system" | "light" | "dark" — see below
formatOnArchive: boolean;
windowOpacity: number; // 0.3–1.0
displayScale: number; // discrete steps: 0.75–2.0
appTitle?: string | null; // OS window title override (clamped to 64 chars)
disableSpotlightSearch: boolean; // fall through to native OS picker when true
showMinimap: boolean; // minimap rail in vertical timeline layout
};
color: ColorStructure; // { ramps, map } — see @takazudo/color-themes
activeDraft: number; // 1–99
draftCount: number; // 1–99
editor: {
vimMode: boolean;
fontFamily: string;
fontSize: number;
lineHeight: number;
paddingHorizontal: number;
paddingVertical: number;
typewriterScrolling: boolean;
showStatusBar: boolean;
markdownListIndent: boolean;
listHangingIndent: boolean;
showLineNumbers: boolean;
lineNumberLeftPadding: number; // gutter left padding, range 0–40 px
showIndentGuides: boolean;
indentType: "tab" | "spaces";
indentSize: number;
directiveCompletion: boolean;
spellcheck: boolean; // underlines misspelled words via the OS dictionary; macOS only
inlineStyles: {
italic: { fontStyle: "normal" | "italic"; fontWeight: number };
emphasis: { fontStyle: "normal" | "italic"; fontWeight: number };
strong: { fontStyle: "normal" | "italic"; fontWeight: number };
};
};
vim: VimSettings;
fontCandidates: string[];
shortcuts: {
// Every shortcut value is string[] — multiple keys per action are supported.
// An empty array [] means unbound.
toggleEditorPreview: string[];
commandPalette: string[];
navInbox: string[];
navArchives: string[];
navSearch: string[];
navTags: string[]; // was navPins in old docs — the actual key is navTags
equalizeLayout: string[];
layoutResetSplit: string[];
toggleVimMode: string[];
openSettings: string[];
reloadApp: string[];
formatMarkdown: string[];
summarizedDraftList: string[];
toggleTodoView: string[];
toggleMindmapView: string[];
printPreview: string[];
showShortcutPanel: string[];
draft1: string[];
// ... draft2 through draft9 (draft10 does not exist)
newDraft: string[];
previousDraft: string[];
nextDraft: string[];
splitFrameRight: string[];
splitFrameLeft: string[];
splitFrameTop: string[];
splitFrameBottom: string[];
focusFrameRight: string[];
focusFrameLeft: string[];
focusFrameTop: string[];
focusFrameBottom: string[];
kanbanMoveDown: string[];
kanbanMoveUp: string[];
kanbanMoveLeft: string[];
kanbanMoveRight: string[];
kanbanEditCard: string[];
kanbanNewCard: string[];
kanbanDeleteCard: string[];
kanbanToggleNotify: string[];
// Pile View shortcuts
pileView: string[];
togglePileViewDirection: string[];
togglePileViewFullContent: string[];
pileViewNext: string[];
pileViewPrev: string[];
pileViewOpenItem: string[];
pileViewArchiveItem: string[];
// Frame-level shortcuts (W5.5)
frameToggleZoom: string[];
frameCollapse: string[];
frameClose: string[];
frameNext: string[];
framePrev: string[];
frameSplitRight: string[];
frameSplitLeft: string[];
frameSplitTop: string[];
frameSplitBottom: string[];
// Open-provider shortcuts (W5.5)
// ... and many more; see AppSettings["shortcuts"] in types.ts for the full list
};
pileView: {
cardWidth: number; // card width in pixels, range 400–800, default 400
};
layout: {
sidebarPosition: "left" | "right";
draftBarCollapsed: boolean;
};
sync: SyncSettings;
/** Preferences only. Calling tokens are never settings. */
docCloud: {
defaultProjectSlug: string | null;
checkpointOnEdit: boolean;
publishNotifications: boolean;
serverOrigin: string;
};
/** Retained name: now the global width of EFE's embedded tree only. */
directoryView: { lastSidebarWidthPx: number };
subscription: SubscriptionInfo;
quickActions: { tiles: QuickAction[] };
/**
* Singleton frameset tree — the live layout for the current app window.
* Replaces the old framesets[]/currentFramesetId pair from Frameset Arch v1.
*/
frameset: FramesetTree;
/**
* Header pin entries displayed as icon buttons in the app toolbar.
* Each pin carries a structural template installed wholesale on activation.
*/
headerLeftPins: HeaderLeftPin[];
/**
* Per-leaf UI state cache, keyed by cache namespace then by leaf frameId.
* Default: {} (empty).
*/
framesetLeafState: Record<string, Record<string, JsonValue>>;
/**
* Most-recently-used ViewProvider ids for the empty-frame nav.
* Order is most-recent-first. Default: [].
*/
framesetRecentProviders: string[];
/** Only docCloud.defaultProjectSlug is in the Doc Cloud override surface. */
deviceOverrides: Record<string, DeviceOverride>;
/**
* Per-surface toolbar item visibility (#6566). Keyed by ToolbarSurfaceId;
* a missing key means every item on that surface is visible. Default: {}.
* `menu-bar-right` is excluded — its visibility lives in
* `menuBar.rightIcons[].visible` instead. See "Toolbar Surfaces" below.
*/
toolbars: Partial<Record<ToolbarSurfaceId, { hidden: string[] }>>;
}Toolbar Surfaces
toolbar-surfaces.ts is the registry every toolbar/header-action surface in the app is declared in once, up front, so adoption sub-tasks never need to touch this package — they read TOOLBAR_SURFACES[surfaceId] instead.
interface ToolbarSurfaceItem {
id: string;
label: string;
}
interface ToolbarSurfaceDef {
label: string;
items: ToolbarSurfaceItem[];
/** Present only for surfaces whose visibility lives outside `toolbars`. */
storage?: "menuBar.rightIcons" | "noteTrayUtility.pinned";
}
const TOOLBAR_SURFACES: Record<ToolbarSurfaceId, ToolbarSurfaceDef>;items lists only items a user may hide — anything that must never be hidden (close, a settings entry point, navigation, tabs) is simply not registered; there is no "locked" state.
HEADER_ACTIONS_SURFACE_BY_PROVIDER: Record<string, ToolbarSurfaceId> maps a ViewProvider.id ("core.kanban-board", "core.dashboard") to the *-header-actions surface its HeaderActions component renders. The Inbox mapping and the note-tray-header-actions surface were removed: History, Pile View and Find similar are Note Tray utilities now (see the next section).
menu-bar-right (storage: "menuBar.rightIcons") and note-tray-utility (storage: "noteTrayUtility.pinned") are the two storage-routed surfaces. For menu-bar-right, that block also carries display order, so it stays the sole authoritative representation and validateSettings() discards any competing toolbars["menu-bar-right"] entry.
Two pure helpers read and write visibility without callers needing to know which storage a surface actually uses:
function isToolbarItemVisible(
settings: Pick<AppSettings, "toolbars" | "menuBar">,
surfaceId: ToolbarSurfaceId,
itemId: string,
): boolean;
function withToolbarItemVisible(
settings: Pick<AppSettings, "toolbars" | "menuBar">,
surfaceId: ToolbarSurfaceId,
itemId: string,
visible: boolean,
): Partial<AppSettings>;withToolbarItemVisible returns the minimal patch: for menu-bar-right it flips visible on the matching rightIcons entry in place (never reordering); for every other surface it patches toolbars[surfaceId].hidden, dropping the surface entry entirely once nothing on it is hidden.
noteTrayUtility (Note Tray utility bar)
AppSettings.noteTrayUtility is the workspace-wide setting for the Note Tray utility bar (the Pattern 4 bar between the tray scope row and the note tabs). Its helpers live in src/.
interface NoteTrayUtilitySettings {
orientation: "horizontal" | "vertical";
showLabels: boolean;
/** Ordered pinned action ids; [] is a valid explicit choice. */
pinned: string[];
/** Vertical width per label mode, in unscaled design px. */
verticalWidth: { labels: number; icons: number };
}| Field | Default | Validation (validateNoteTrayUtility) |
|---|---|---|
orientation | "horizontal" | Unknown value falls back to the default |
showLabels | true | Non-boolean falls back to the default |
pinned | ["to-ai", "sticker", "preview", "pile-view"] | Duplicates removed, unknown ids dropped, an explicit [] is kept |
verticalWidth.labels | 144 (96–240, step 8) | Missing, non-finite or out-of-range falls back to the mode default; in-range values snap to the 8 px step |
verticalWidth.icons | 48 (48–160, step 8) | Same rule |
Exports: NOTE_TRAY_UTILITY_ACTIONS (the pinnable ids, their labels and More groups Current note / Organize / Tray), NOTE_TRAY_UTILITY_DEFAULT_PINNED, NOTE_TRAY_UTILITY_WIDTH, NOTE_TRAY_UTILITY_MIN_EDITOR_PX (160), defaultNoteTrayUtilitySettings, noteTrayUtilityWidthMode, validNoteTrayUtilityWidth, validateNoteTrayUtility, withNoteTrayUtilityPinMoved and activeNoteTrayUtilityWidth.
More and Customize are deliberately absent from NOTE_TRAY_UTILITY_ACTIONS, so they can never be unpinned. The renderer applies --display-scale once and clamps the rendered width to leave NOTE_TRAY_UTILITY_MIN_EDITOR_PX for the editor; that clamp is never written back to the setting. The bundled tauri- carries the same defaults.
general.colorMode
general.colorMode is a ColorMode — COLOR_MODES gives the three values as ["system", "light", "dark"] as const. It is distinct from SchemeMode (@takazudo/color-themes), which has only the resolved two-valued "light" | "dark": "system" follows the OS appearance and is resolved down to a SchemeMode at runtime by the effective-mode store, not by this package. colorScheme still names which registry scheme is active (currently always "default" — see @takazudo/color-themes); colorMode picks which of that scheme's two palettes is displayed. validateSettings() enum-validates colorMode against COLOR_MODES and falls back to the default ("system") on an unknown value. colorScheme itself is only checked for being a string here — healing an unknown scheme name (e.g. a pre-restructure default-dark/default-light) is the Settings Doctor's job, not validateSettings()'s; see Settings Doctor.
HeaderLeftPin
interface HeaderLeftPin {
id: string; // stable kebab-case id, e.g. "inbox-default"
template: PinTemplate;
label: string; // display label and tooltip text
iconId: string; // Lucide icon name, e.g. "inbox", "archive"
routeSlug: string | null; // used for /p/:slug routes; null for built-in pins
visible: boolean;
providerProps?: Record<string, unknown>; // known shapes catalogued by PinProviderPropsByProviderId
}
interface PinTemplate {
tree: FramesetTree;
activeFrameId?: string;
}PinProviderPropsByProviderId["core.doc-cloud"] permits only projectSlug, initialSurface, editorLayout, and outlineCollapsed. Doc Cloud pins are one-leaf templates. PinProviderPropsByProviderId["core.external-file-editor"] permits initialFiles, initialTreeRoot, and treeCollapsed; the former Directory View is not a provider-props target.
QuickAction
type QuickActionStep = { commandId: string };
type QuickAction = {
id: string;
name: string;
iconId: string;
aliases: string[];
steps: QuickActionStep[];
};SyncSettings
interface SyncSettings {
// Cloud sync
cloudDeviceId: string;
cloudDeviceName: string;
cloudRealtimeEnabled: boolean;
}VimSettings
interface VimSettings {
clipboardSync: boolean;
showModeIndicator: boolean;
vimrc: string;
}Default Values
Editor
| Setting | Default |
|---|---|
vimMode | true |
fontFamily | "JetBrains Mono" |
fontSize | 16 |
lineHeight | 1.6 |
paddingHorizontal | 12 |
paddingVertical | 8 |
typewriterScrolling | false |
showStatusBar | true |
markdownListIndent | true |
listHangingIndent | true |
showLineNumbers | true |
lineNumberLeftPadding | 12 |
showIndentGuides | true |
indentType | "spaces" |
indentSize | 2 |
directiveCompletion | true |
spellcheck | false |
inlineStyles.italic | { fontStyle: "italic", fontWeight: 400 } |
inlineStyles.emphasis | { fontStyle: "italic", fontWeight: 400 } |
inlineStyles.strong | { fontStyle: "normal", fontWeight: 700 } |
Vim
| Setting | Default |
|---|---|
clipboardSync | true |
showModeIndicator | true |
vimrc | "" |
Shortcuts
Every shortcut value is string[]. An empty array [] means the action is unbound. Multiple key chords can be assigned to the same action — all of them trigger it.
Runtime shortcut profiles
ShortcutProfileId is either "desktop" or "web". applyShortcutProfile(base, profile, options?) returns an effective shortcut map and a provenance map without mutating base. The desktop profile is an identity copy. The web profile remaps only defaults that still match their value in defaultShortcuts; a customized base binding is left as the user set it. The workspace-synced shortcut arrays remain the base map.
| Default action | Base combo | Web-profile combo |
|---|---|---|
newDraft | Mod+N | Mod+Alt+Shift+N |
openNotificationCenter | Mod+Shift+N | Mod+Alt+Shift+B |
toggleTodoView | Mod+Shift+T | Mod+Alt+Shift+T |
previousDraft / nextDraft | Mod+Shift+[ / Mod+Shift+] | Mod+Alt+Shift+[ / Mod+Alt+Shift+] |
frameNext / framePrev | Ctrl+Tab / Ctrl+Shift+Tab | Mod+Alt+Shift+. / Mod+Alt+Shift+, |
reloadApp | Mod+R | disabled (the browser reloads the page) |
openSnippetPalette | Mod+Shift+I | Mod+Alt+Shift+I |
insertComponent | Mod+Alt+C | Mod+Alt+Shift+C |
openAuthoringHelp | Mod+Shift+/ | Mod+Alt+Shift+/ |
frameSplitRight | Mod+Shift+Backslash | Mod+Alt+Shift+Backslash |
checkDiff | Mod+Shift+D | Mod+Alt+Shift+D |
commandPalette | Mod+K | keeps Mod+K and adds Mod+Alt+Shift+K |
inlineAiCommandTrigger | Mod-j | keeps Mod-j and adds Mod-Alt-Shift-j (CodeMirror syntax) |
For a replacement, provenance records the effective combo with origin: "replaced" and its baseCombo. A keep-and-add alias has origin: "added" and also records its source combo; an unchanged binding has origin: "base". reloadApp has an empty effective combo provenance entry to record that its default was disabled; it is not an executable binding.
When a user edits the effective map, call translateShortcutEdit(base, provenance, edit) and assign the returned array to base[edit.key]. This maps a web-view edit back to the underlying base: removing a generated replacement removes its source binding, while removing an added alias leaves the original binding in place. Saving an unchanged effective value also preserves defaults that have no web binding.
The two keep-and-add aliases (commandPalette and inlineAiCommandTrigger) can be hidden on one web device. Pass their shortcut keys in applyShortcutProfile's optional suppressedAddedAliases set. After an edit, pass the current set, provenance, and edit to updateWebShortcutAliasSuppressions; persist and reload the returned set with writeWebShortcutAliasSuppressions() and readWebShortcutAliasSuppressions() in the renderer helper tauri-, which uses device-local localStorage. These suppressions are local preferences, not fields in AppSettings, so suppressing an alias does not change the synced base shortcut.
Browser-reserved shortcut inventory
BROWSER_RESERVED_SHORTCUTS lists confirmed browser-chrome shortcuts that are swallowed before the page receives them. The table intentionally omits combinations marked preventable or unverified in the investigation. findBrowserConflicts(shortcuts, browser) checks this inventory and includes a suggested alternative when one is available; suggestWebAlternative uses the explicit web remap for known defaults and otherwise applies the reserved-prefix rule while retaining the final key.
| Browser family | OS | Confirmed reserved combinations |
|---|---|---|
| Chromium | macOS | Mod+N, Mod+Shift+N, Mod+Shift+T, Mod+Shift+[, Mod+Shift+], Ctrl+Tab, Ctrl+Shift+Tab |
| Chromium | Windows | Mod+N, Mod+Shift+N, Mod+Shift+T, Ctrl+Tab, Ctrl+Shift+Tab, Mod+Shift+I |
| Safari | macOS | Mod+N, Mod+Shift+N, Ctrl+Tab, Ctrl+Shift+Tab |
| Safari | iPadOS | Mod+N, Mod+Shift+T |
The inventory is browser-specific: an absent family/OS entry means this table currently has no confirmed reserved combos for that pair, not that every shortcut is guaranteed to reach the app. Update the table when browser verification changes the evidence.
| Action | Default |
|---|---|
toggleEditorPreview | ["Mod+E"] |
commandPalette | ["Mod+K"] |
openSettings | ["Mod+,"] |
draft1–draft9 | ["Mod+1"]–["Mod+9"] |
newDraft | ["Mod+N"] |
previousDraft | ["Mod+Shift+["] |
nextDraft | ["Mod+Shift+]"] |
kanbanMoveDown / Up / Left / Right | ["J"] / ["K"] / ["H"] / ["L"] |
kanbanEditCard | ["E"] |
kanbanNewCard | ["N"] |
kanbanDeleteCard | ["D"] |
showShortcutPanel | ["?"] |
mindmapMoveDown / Up | ["ArrowDown"] / ["ArrowUp"] |
mindmapCollapse / Expand | ["ArrowLeft"] / ["ArrowRight"] |
mindmapAddChild | ["Tab"] |
mindmapAddSibling | ["Enter"] |
mindmapInsertParent | ["Alt+Tab"] |
mindmapOutdentNode | ["Mod+ArrowLeft", "Shift+Tab"] |
mindmapDeleteNode | ["Backspace", "Delete"] |
mindmapDeleteKeepChildren | ["Alt+Backspace"] |
mindmapEditNode | ["Mod+Enter"] |
mindmapSelectAll | ["Mod+A"] |
frameNext | ["Ctrl+Tab"] |
framePrev | ["Ctrl+Shift+Tab"] |
frameSplitRight | ["Mod+Shift+Backslash"] |
Pile View shortcuts:
| Action | Default |
|---|---|
pileView | [] (unbound — assign in Settings → Shortcuts) |
togglePileViewDirection | [] (opt-in) |
togglePileViewFullContent | [] (opt-in) |
pileViewNext | ["J", "L", "ArrowRight", "ArrowDown"] |
pileViewPrev | ["K", "H", "ArrowLeft", "ArrowUp"] |
pileViewOpenItem | ["Enter"] |
pileViewArchiveItem | ["A"] |
Shortcuts for split frame operations, focus frame navigation, and most navigation keys (navInbox, navArchives, navSearch, navTags, equalizeLayout, layoutResetSplit, toggleVimMode, reloadApp, formatMarkdown, summarizedDraftList, toggleTodoView, toggleMindmapView, printPreview) all default to [] (unbound).
Layout
| Setting | Default |
|---|---|
sidebarPosition | "left" |
draftBarCollapsed | false |
General
| Setting | Default |
|---|---|
colorScheme | "default" |
colorMode | "system" |
formatOnArchive | false |
windowOpacity | 1.0 |
displayScale | 1.0 |
appTitle | null |
disableSpotlightSearch | false |
showMinimap | true |
Color
AppSettings["color"] defaults to defaultColorStructure, which is seedColorStructure(getSchemeByName(defaultThemeName)) — a deep clone of the default scheme's { ramps, modes: { light, dark } }. This is the persisted shape: since epic #5893 one scheme owns both appearances, so the block carries BOTH mode maps and validateColorStructure() rejects (and reseeds) anything that supplies only one.
A second export, defaultResolvedColors (= resolveScheme(getSchemeByName(defaultThemeName))), is the same default scheme already walked through every RampRef into concrete ColorSettings colors — used wherever a component needs resolved colors rather than the ramp structure (e.g. before the first applyColors() call). defaultColorSettings is a deprecated alias for defaultResolvedColors, kept only until call sites migrate.
Pile View
| Setting | Default |
|---|---|
cardWidth | 400 (range 400–800 px) |
Sync
| Setting | Default |
|---|---|
cloudDeviceId | "" |
cloudDeviceName | "" |
cloudRealtimeEnabled | true |
Doc Cloud
| Setting | Default |
|---|---|
defaultProjectSlug | null (open Projects) |
checkpointOnEdit | true |
publishNotifications | true |
serverOrigin | "" (use adapter origin) |
Credentials are intentionally absent. The only device-overridable Doc Cloud field is defaultProjectSlug; an explicit null override means Projects.
Embedded EFE tree width
defaultDirectoryViewSettings is { lastSidebarWidthPx: 240 }. The historical settings key remains, but it controls the tree pane inside External File Editor; there is no registered standalone Directory View provider.
Quick Actions
Default: { tiles: [] } (no quick actions)
Drafts
| Setting | Default |
|---|---|
activeDraft | 1 |
draftCount | 1 |
Toolbars
Default: {} (every item on every registered surface is visible).
Font Candidates
Default list of font families including JetBrains Mono, Fira Code, Hack, Menlo, Monaco, SF Mono, and Nerd Font variants. Used by the FontPicker component.
validateSettings()
Validates and sanitizes an unknown input into a valid AppSettings object. Returns null if the input is not an object.
function validateSettings(settings: unknown): AppSettings | null;Used in both the settings context (on load) and the settings dialog (on save) to enforce valid configuration at all times.
Key behaviors:
Falls back to defaults — missing or invalid fields are replaced with defaults
Range validation — numeric fields are clamped (e.g., fontSize 10–24, lineHeight 1.0–2.0, windowOpacity 0.3–1.0, activeDraft/draftCount 1–99 integer, pileView.cardWidth 400–800, lineNumberLeftPadding 0–40)
String length limits — vimrc is reset to empty string if it exceeds 4096 characters; appTitle is clamped to 64 characters
Schema migration — handles renamed fields:
general.theme/general.colorSchema→general.colorSchemeactiveTab→activeDraft,tabCount→draftCountshortcuts.tab1–tab9→shortcuts.draft1–draft9shortcuts.draft10is deleted (Mod+0 is reserved for display scale reset)mindmap.depthColor*block is dropped (now controlled by color scheme tokens)
Color validation —
coloris validated as a wholeColorStructure: ramp array lengths (base5,accent3), every color string (hex,oklch(...), ortransparent), and everyRampRef(a literal color string, or a{ base | accent: n }index within range /{ state: role }) must all be structurally valid, or the entirecolorfield is discarded and re-seeded fromdefaultColorStructure— there is no per-field fallback the way other settings sections workFrameset validation — validates
framesettree structure; falls back todefaultFramesetTreeon invalid input; wipesframesetLeafStateon v1→v2 migrationDoc Cloud validation — validates the default-project slug, booleans, and bare server origin; drops credential-like unknown fields; validates Doc Cloud pin props to the four safe seeds
Retired-provider no-migration behavior — provider ids are opaque. Old pre-release Directory View pins are preserved without a compatibility reader and may show provider-not-found until the user removes them or resets settings
Vim settings validation — validates
clipboardSync,showModeIndicator(booleans), andvimrc(string with length cap)Note Tray utility validation —
noteTrayUtilityis normalised byvalidateNoteTrayUtility(see above); a missing block takes the defaultsToolbar visibility validation (#6566) — for each
toolbarsentry: unknown surface ids are dropped, malformed surface objects (non-object, or missinghidden) are dropped, unknown item ids and non-string entries are filtered out ofhidden, duplicates are removed, a non-arrayhiddenbecomes[], and anytoolbars["menu-bar-right"]entry is discarded (that surface's sole representation ismenuBar.rightIcons)
Dependencies
@takazudo/color-themes— used to generate default color values from the default theme@takazudo/shortcut-engine— used for shortcut normalization and deduplication invalidateSettings@takazudo/view-provider— providesFramesetTreetype andvalidateFramesetTreeused by validation