Procházet zdrojové kódy

refactor(client): keep settings constants and schemas off the client contract surfaces

The /client entry of a UI plugin exports no values beyond what cordis
loading needs; the theme constants block returns to type-only re-exports,
the per-namespace schemas move into the shared *-settings modules instead
of widening the host entries, and same-package specs import those internals
directly per the export discipline in packages/client/AGENTS.md.
Yichen Jiang před 2 měsíci
rodič
revize
53c66ecbeb

+ 1 - 9
packages/client/locale/src/index.ts

@@ -1,22 +1,14 @@
 /** Host registration for the browser locale preference. */
 
 import type { Context } from 'cordis'
-import z from 'schemastery'
 import { settingsNamespace } from '@deepseek-ai/dsh-settings'
-import {
-  LOCALE_IDS, LOCALE_PREFERENCE_FIELD, LOCALE_SETTINGS_NAMESPACE, type LocaleSettings,
-} from './locale-settings.ts'
+import { LOCALE_SETTINGS_NAMESPACE, LocaleSettingsSchema } from './locale-settings.ts'
 
 export {
   LOCALE_IDS, LOCALE_PREFERENCE_FIELD, LOCALE_SETTINGS_NAMESPACE,
   type LocaleId, type LocaleSettings,
 } from './locale-settings.ts'
 
-/** Durable locale schema; also the wire envelope the browser scope validates against. */
-export const LocaleSettingsSchema: z<LocaleSettings> = z.object({
-  [LOCALE_PREFERENCE_FIELD]: z.union([...LOCALE_IDS]).required(false),
-})
-
 /**
  * Register the durable locale section when a settings provider exists.
  * @param ctx - Host context whose optional settings service owns the section.

+ 7 - 0
packages/client/locale/src/locale-settings.ts

@@ -1,5 +1,7 @@
 /** Locale preference stored in the Host user-settings document. */
 
+import z from 'schemastery'
+
 /** Settings namespace owned by the locale plugin. */
 export const LOCALE_SETTINGS_NAMESPACE = 'locale'
 
@@ -17,3 +19,8 @@ export interface LocaleSettings {
   /** Explicit locale selection; absence delegates to the browser. */
   preference?: LocaleId
 }
+
+/** Durable locale schema; also the wire envelope the browser scope validates against. */
+export const LocaleSettingsSchema: z<LocaleSettings> = z.object({
+  [LOCALE_PREFERENCE_FIELD]: z.union([...LOCALE_IDS]).required(false),
+})

+ 1 - 2
packages/client/locale/tests/apply.spec.ts

@@ -8,8 +8,7 @@ import {
   apply, inject, SETTINGS_NS,
 } from '@deepseek-ai/dsh-client-locale/client'
 import type { LanguageRowInjected, LocaleService } from '@deepseek-ai/dsh-client-locale/client'
-import { LOCALE_SETTINGS_NAMESPACE } from '../src/locale-settings.ts'
-import { LocaleSettingsSchema } from '../src/index.ts'
+import { LOCALE_SETTINGS_NAMESPACE, LocaleSettingsSchema } from '../src/locale-settings.ts'
 import { LanguageRow } from '../src/client/LanguageRow.tsx'
 import type { createLanguageRowStore } from '../src/client/settings-store.ts'
 

+ 1 - 10
packages/client/ui-conversation/src/index.ts

@@ -1,23 +1,14 @@
 /** Host registration for browser conversation preferences. */
 
 import type { Context } from 'cordis'
-import z from 'schemastery'
 import { settingsNamespace } from '@deepseek-ai/dsh-settings'
-import {
-  BUSY_ENTER_BEHAVIORS, BUSY_ENTER_FIELD, CONVERSATION_SETTINGS_NAMESPACE,
-  DEFAULT_BUSY_ENTER_BEHAVIOR, type ConversationSettings,
-} from './submission-settings.ts'
+import { CONVERSATION_SETTINGS_NAMESPACE, ConversationSettingsSchema } from './submission-settings.ts'
 
 export {
   BUSY_ENTER_BEHAVIORS, BUSY_ENTER_FIELD, CONVERSATION_SETTINGS_NAMESPACE,
   DEFAULT_BUSY_ENTER_BEHAVIOR, type BusyEnterBehavior, type ConversationSettings,
 } from './submission-settings.ts'
 
-/** Durable conversation schema; also the wire envelope the browser scope validates against. */
-export const ConversationSettingsSchema: z<ConversationSettings> = z.object({
-  [BUSY_ENTER_FIELD]: z.union([...BUSY_ENTER_BEHAVIORS]).default(DEFAULT_BUSY_ENTER_BEHAVIOR),
-})
-
 /**
  * Register the durable conversation section when a settings provider exists.
  * @param ctx - Host context whose optional settings service owns the section.

+ 7 - 0
packages/client/ui-conversation/src/submission-settings.ts

@@ -1,5 +1,7 @@
 /** Busy-Enter preference stored in the Host user-settings document. */
 
+import z from 'schemastery'
+
 /** Settings namespace owned by the conversation plugin. */
 export const CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation'
 
@@ -20,3 +22,8 @@ export interface ConversationSettings {
   /** Delivery mode for plain Enter while the addressed agent is busy. */
   busyEnter: BusyEnterBehavior
 }
+
+/** Durable conversation schema; also the wire envelope the browser scope validates against. */
+export const ConversationSettingsSchema: z<ConversationSettings> = z.object({
+  [BUSY_ENTER_FIELD]: z.union([...BUSY_ENTER_BEHAVIORS]).default(DEFAULT_BUSY_ENTER_BEHAVIOR),
+})

+ 1 - 4
packages/client/ui-theme/src/client/index.ts

@@ -26,10 +26,7 @@ import {
 export type { AppearanceRowComponentProps, AppearanceRowInjected } from './AppearanceRow.tsx'
 export type { AppearanceRowState } from './settings-store.ts'
 export type { ThemeKey } from './locales.ts'
-export {
-  DEFAULT_PREFERENCE, THEME_PREFERENCE_FIELD, THEME_PREFERENCES, THEME_SETTINGS_NAMESPACE,
-  type ThemePreference, type ThemeSettings,
-} from '../theme-settings.ts'
+export type { ThemePreference, ThemeSettings } from '../theme-settings.ts'
 
 /** Namespace owning this feature's settings-row copy. */
 export const SETTINGS_NS = 'settings.theme'

+ 1 - 10
packages/client/ui-theme/src/index.ts

@@ -1,23 +1,14 @@
 /** Host registration for the browser theme preference. */
 
 import type { Context } from 'cordis'
-import z from 'schemastery'
 import { settingsNamespace } from '@deepseek-ai/dsh-settings'
-import {
-  DEFAULT_PREFERENCE, THEME_PREFERENCE_FIELD, THEME_PREFERENCES, THEME_SETTINGS_NAMESPACE,
-  type ThemeSettings,
-} from './theme-settings.ts'
+import { THEME_SETTINGS_NAMESPACE, ThemeSettingsSchema } from './theme-settings.ts'
 
 export {
   DEFAULT_PREFERENCE, THEME_PREFERENCE_FIELD, THEME_PREFERENCES, THEME_SETTINGS_NAMESPACE,
   type ThemePreference, type ThemeSettings,
 } from './theme-settings.ts'
 
-/** Durable theme schema; also the wire envelope the browser scope validates against. */
-export const ThemeSettingsSchema: z<ThemeSettings> = z.object({
-  [THEME_PREFERENCE_FIELD]: z.union([...THEME_PREFERENCES]).default(DEFAULT_PREFERENCE),
-})
-
 /**
  * Register the durable theme section when a settings provider exists.
  * @param ctx - Host context whose optional settings service owns the section.

+ 7 - 0
packages/client/ui-theme/src/theme-settings.ts

@@ -1,5 +1,7 @@
 /** Theme preferences stored in the Host user-settings document. */
 
+import z from 'schemastery'
+
 /** Built-in preferences accepted at the registry and settings boundaries. */
 export const THEME_PREFERENCES = ['light', 'dark', 'system'] as const
 
@@ -21,6 +23,11 @@ export interface ThemeSettings {
   preference: ThemePreference
 }
 
+/** Durable theme schema; also the wire envelope the browser scope validates against. */
+export const ThemeSettingsSchema: z<ThemeSettings> = z.object({
+  [THEME_PREFERENCE_FIELD]: z.union([...THEME_PREFERENCES]).default(DEFAULT_PREFERENCE),
+})
+
 /**
  * Narrow one wire or registry value to a persistable preference.
  * @param value - value crossing the settings or registry boundary.

+ 2 - 4
packages/client/ui-theme/tests/apply.spec.ts

@@ -6,11 +6,9 @@ import { describe, expect, it, vi } from 'vitest'
 import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client'
 import { LocaleService } from '@deepseek-ai/dsh-client-locale/client'
 import { usePinnedBrowserLanguages } from '@deepseek-ai/dsh-client-test-runtime'
-import {
-  apply, inject, SETTINGS_NS, THEME_SETTINGS_NAMESPACE,
-} from '@deepseek-ai/dsh-client-ui-theme/client'
+import { apply, inject, SETTINGS_NS } from '@deepseek-ai/dsh-client-ui-theme/client'
 import type { AppearanceRowInjected, ThemeService } from '@deepseek-ai/dsh-client-ui-theme/client'
-import { ThemeSettingsSchema } from '@deepseek-ai/dsh-client-ui-theme'
+import { THEME_SETTINGS_NAMESPACE, ThemeSettingsSchema } from '../src/theme-settings.ts'
 import { AppearanceRow } from '../src/client/AppearanceRow.tsx'
 import type { createAppearanceRowStore } from '../src/client/settings-store.ts'