@huanlin/dsh-plugin-sidebar-brand-text 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/lib/client.js +3 -3
- package/lib/client.js.map +1 -1
- package/lib/index.js +1 -2
- package/lib/types/client/controller.d.ts +1 -1
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/titleWriter.d.ts +1 -1
- package/lib/types/settings.d.ts +1 -1
- package/package.json +23 -28
- package/lib/invariant.js +0 -21
- package/lib/types/invariant.d.ts +0 -10
package/README.md
CHANGED
|
@@ -69,15 +69,17 @@ DSH 的 `document.title` 由 `packages/client/ui-renderer/src/client/DocumentTit
|
|
|
69
69
|
|
|
70
70
|
## 开发
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
前置:本插件适配 DSH `v0.1.2-rc.1`。alpha 版本未发 npm,`@deepseek-ai/dsh-*` 只作 peerDependencies 声明(`^0.1.2-alpha.1`,不安装);dev 期类型用 tsconfig `paths` 指向本地 DSH 源码树(`~/.dsh/source/current`,需已 `pnpm run build`),并在 `node_modules/@deepseek-ai/` 下建 junction 指向对应包目录(同 `dsh-plugin-interpreters` 的做法)。仅 `@deepseek-ai/cordis`(`^4.0.1`)与 `@deepseek-ai/schemastery`(`^3.18.1`)已发 npm、保留在 devDependencies。
|
|
73
73
|
|
|
74
74
|
```sh
|
|
75
|
-
pnpm install # 安装 registry
|
|
76
|
-
pnpm run typecheck # tsc --noEmit
|
|
77
|
-
pnpm test # vitest:注册形态 + 控制器 +
|
|
78
|
-
pnpm run build # tsdown + tsc → lib/index.js、lib/
|
|
75
|
+
pnpm install # 安装 registry 依赖(@deepseek-ai/dsh-* peers 不拉取)
|
|
76
|
+
pnpm run typecheck # tsc --noEmit(类型经 tsconfig paths 解析到 DSH 源码树)
|
|
77
|
+
pnpm test # vitest:注册形态 + 控制器 + 组件渲染(dsh-client-store 用本地测试替身)
|
|
78
|
+
pnpm run build # tsdown + tsc → lib/index.js、lib/client.js、lib/types/
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
> 注:本插件不发布 `./invariant` 导出。唯一的 `sidebar.brand.name` slot 注册由声明感知的 `slots.inject()` 提供回滚,不存在独立可分歧的观察,不符合 DSH v0.1.2-rc.1 收紧后的 invariant 发布规则(禁止空 installer 与「服务存在性检查」式 invariant)。
|
|
82
|
+
|
|
81
83
|
预构建 `lib/` 策略:`lib/` 入库(不在 `.gitignore` 中),无 `prepare` 脚本。`github:` 安装开箱即用。
|
|
82
84
|
|
|
83
85
|
## 运行(挂载到 profile)
|
package/lib/client.js
CHANGED
|
@@ -25,8 +25,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
//#endregion
|
|
26
26
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
27
27
|
react_jsx_runtime = __toESM(react_jsx_runtime);
|
|
28
|
-
let
|
|
29
|
-
|
|
28
|
+
let __deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
29
|
+
__deepseek_ai_dsh_client_store = __toESM(__deepseek_ai_dsh_client_store);
|
|
30
30
|
let react = require("react");
|
|
31
31
|
react = __toESM(react);
|
|
32
32
|
|
|
@@ -715,7 +715,7 @@ var BrandTextSettingsController = class {
|
|
|
715
715
|
loaded = false;
|
|
716
716
|
generation = 0;
|
|
717
717
|
constructor() {
|
|
718
|
-
this.store = (0,
|
|
718
|
+
this.store = (0, __deepseek_ai_dsh_client_store.createSnapshotStore)(initialState());
|
|
719
719
|
}
|
|
720
720
|
/** Fetch the config from `/sbbt/api/get` and update the store. */
|
|
721
721
|
async load() {
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["dicts: Record<string, Record<BrandTextKey, string>>","DEFAULT_BRAND_TEXT_CONFIG: BrandTextConfig","cfg: BrandTextConfig","cardStyle: CSSProperties","headerStyle: CSSProperties","headTextStyle: CSSProperties","nameStyle: CSSProperties","descStyle: CSSProperties","pendingStyle: CSSProperties","bodyStyle: CSSProperties","formStyle: CSSProperties","fieldStyle: CSSProperties","labelStyle: CSSProperties","inputStyle: CSSProperties","hintStyle: CSSProperties","footerStyle: CSSProperties","btnBase: CSSProperties","noticeStyle: CSSProperties","savedStyle: CSSProperties","errorStyle: CSSProperties","body: React.ReactNode","cfg: BrandTextConfig","observer: MutationObserver | null","en: Record<BrandTextKey, string>","zh: Record<BrandTextKey, string>","dispose: (() => void) | undefined"],"sources":["../src/client/dictionaries.ts","../src/types.ts","../src/client/BrandText.tsx","../src/client/BrandTextCard.tsx","../src/client/controller.ts","../src/client/bindSnapshotSelector.ts","../src/client/titleWriter.ts","../src/client/locales.ts","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Override dictionaries for the `dsh-plugin-sidebar-brand-text` namespace,\n * registered with the better-locale override store (`ctx.betterLocale`)\n * when that plugin is installed. Keyed by locale id; every dictionary\n * covers the same keys as the native zh/en copy in `locales.ts`.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/dictionaries\n */\n\nimport type { BrandTextKey } from './locales.ts'\n\n/**\n * Locale-id keyed override dictionaries, one full copy per language.\n * The dict shape matches `BetterLocaleStore.register(ns, dicts)` where\n * `dicts` is `Record<localeId, Record<key, string>>`.\n */\nexport const dicts: Record<string, Record<BrandTextKey, string>> = {\n ja: {\n 'card.title': 'サイドバーのブランドテキスト',\n 'card.intro': 'サイドバーのブランド名とリビジョンバッジをカスタムテキストに置き換えます。',\n 'card.unsaved': '未保存',\n 'card.saved': '保存済み',\n 'card.saving': '保存中…',\n 'card.discard': '破棄',\n 'card.save': '保存',\n 'card.unavailable': 'サイドバー・ブランドテキストの設定チャンネルを利用できません。後でもう一度お試しください。',\n 'card.retry': '再試行',\n 'field.name.label': 'ブランド名',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'サイドバーでロゴの右隣に表示されるテキスト。既定の「DSH Local Build」を置き換えます。',\n 'field.revision.label': 'リビジョンバッジ',\n 'field.revision.placeholder': '例:v1.0.0 または abc1234',\n 'field.revision.hint': 'ブランド名の右隣に表示される小さなバッジテキスト。空にするとバッジを非表示にします。',\n },\n de: {\n 'card.title': 'Seitenleisten-Brand-Text',\n 'card.intro': 'Ersetzt den Markennamen und das Revisions-Abzeichen in der Seitenleiste durch benutzerdefinierten Text.',\n 'card.unsaved': 'Nicht gespeichert',\n 'card.saved': 'Gespeichert',\n 'card.saving': 'Wird gespeichert…',\n 'card.discard': 'Verwerfen',\n 'card.save': 'Speichern',\n 'card.unavailable': 'Der Konfigurationskanal „sidebar-brand-text“ ist derzeit nicht verfügbar. Versuchen Sie es später erneut.',\n 'card.retry': 'Erneut versuchen',\n 'field.name.label': 'Markenname',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Text neben dem Logo in der Seitenleiste. Ersetzt den Standardwert „DSH Local Build“.',\n 'field.revision.label': 'Revisions-Abzeichen',\n 'field.revision.placeholder': 'z. B. v1.0.0 oder abc1234',\n 'field.revision.hint': 'Kleiner Abzeichentext neben dem Markennamen. Leer lassen, um das Abzeichen auszublenden.',\n },\n fr: {\n 'card.title': 'Texte de marque de la barre latérale',\n 'card.intro': 'Remplace le nom de la marque et le badge de révision de la barre latérale par un texte personnalisé.',\n 'card.unsaved': 'Non enregistré',\n 'card.saved': 'Enregistré',\n 'card.saving': 'Enregistrement…',\n 'card.discard': 'Annuler',\n 'card.save': 'Enregistrer',\n 'card.unavailable': 'Le canal de configuration sidebar-brand-text est indisponible. Veuillez réessayer plus tard.',\n 'card.retry': 'Réessayer',\n 'field.name.label': 'Nom de marque',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Texte affiché dans la barre latérale à côté du logo. Remplace le « DSH Local Build » par défaut.',\n 'field.revision.label': 'Badge de révision',\n 'field.revision.placeholder': 'p. ex. v1.0.0 ou abc1234',\n 'field.revision.hint': 'Petit badge à côté du nom de la marque. Laisser vide pour masquer le badge.',\n },\n pt: {\n 'card.title': 'Texto da Marca na Barra Lateral',\n 'card.intro': 'Substitui o nome da marca e o selo de revisão da barra lateral por texto personalizado.',\n 'card.unsaved': 'Não salvo',\n 'card.saved': 'Salvo',\n 'card.saving': 'Salvando…',\n 'card.discard': 'Descartar',\n 'card.save': 'Salvar',\n 'card.unavailable': 'O canal de configuração do sidebar-brand-text está indisponível. Tente novamente mais tarde.',\n 'card.retry': 'Tentar novamente',\n 'field.name.label': 'Nome da marca',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Texto exibido na barra lateral ao lado do logotipo. Substitui o padrão \"DSH Local Build\".',\n 'field.revision.label': 'Selo de revisão',\n 'field.revision.placeholder': 'por exemplo, v1.0.0 ou abc1234',\n 'field.revision.hint': 'Texto pequeno ao lado do nome da marca. Deixe vazio para ocultar o selo.',\n },\n ko: {\n 'card.title': '사이드바 브랜드 텍스트',\n 'card.intro': '사이드바의 브랜드 이름과 리비전 배지를 사용자 지정 텍스트로 바꿉니다.',\n 'card.unsaved': '저장 안 됨',\n 'card.saved': '저장됨',\n 'card.saving': '저장 중…',\n 'card.discard': '취소',\n 'card.save': '저장',\n 'card.unavailable': 'sidebar-brand-text 구성 채널을 사용할 수 없습니다. 나중에 다시 시도하세요.',\n 'card.retry': '다시 시도',\n 'field.name.label': '브랜드 이름',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '사이드바에서 로고 옆에 표시되는 텍스트입니다. 기본값인 \"DSH Local Build\"를 대체합니다.',\n 'field.revision.label': '리비전 배지',\n 'field.revision.placeholder': '예: v1.0.0 또는 abc1234',\n 'field.revision.hint': '브랜드 이름 옆에 표시되는 작은 배지 텍스트입니다. 비워 두면 배지가 표시되지 않습니다.',\n },\n ar: {\n 'card.title': 'نص العلامة في الشريط الجانبي',\n 'card.intro': 'استبدل اسم العلامة وشارة المراجعة في الشريط الجانبي بنص مخصص.',\n 'card.unsaved': 'غير محفوظ',\n 'card.saved': 'محفوظ',\n 'card.saving': 'جارٍ الحفظ…',\n 'card.discard': 'تجاهل',\n 'card.save': 'حفظ',\n 'card.unavailable': 'قناة إعدادات نص العلامة الجانبية غير متاحة. يرجى المحاولة لاحقًا.',\n 'card.retry': 'إعادة المحاولة',\n 'field.name.label': 'اسم العلامة',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'النص المعروض في الشريط الجانبي بجانب الشعار. يستبدل النص الافتراضي «DSH Local Build».',\n 'field.revision.label': 'شارة المراجعة',\n 'field.revision.placeholder': 'مثل v1.0.0 أو abc1234',\n 'field.revision.hint': 'نص الشارة الصغيرة بجانب اسم العلامة. اتركه فارغًا لإخفاء الشارة.',\n },\n hi: {\n 'card.title': 'साइडबार ब्रांड टेक्स्ट',\n 'card.intro': 'साइडबार का ब्रांड नाम और रिवीज़न बैज कस्टम टेक्स्ट से बदलें।',\n 'card.unsaved': 'सहेजा नहीं गया',\n 'card.saved': 'सहेजा गया',\n 'card.saving': 'सहेजा जा रहा है…',\n 'card.discard': 'छोड़ें',\n 'card.save': 'सहेजें',\n 'card.unavailable': 'sidebar-brand-text कॉन्फ़िगरेशन चैनल उपलब्ध नहीं है। कृपया बाद में पुनः प्रयास करें।',\n 'card.retry': 'पुनः प्रयास करें',\n 'field.name.label': 'ब्रांड नाम',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'साइडबार में लोगो के बगल में दिखाया जाने वाला टेक्स्ट। डिफ़ॉल्ट \"DSH Local Build\" को बदलता है।',\n 'field.revision.label': 'रिवीज़न बैज',\n 'field.revision.placeholder': 'जैसे v1.0.0 या abc1234',\n 'field.revision.hint': 'ब्रांड नाम के बगल में छोटा बैज टेक्स्ट। बैज छिपाने के लिए खाली छोड़ें।',\n },\n id: {\n 'card.title': 'Teks Merek Bilah Sisi',\n 'card.intro': 'Ganti nama merek dan lencana revisi di bilah sisi dengan teks khusus.',\n 'card.unsaved': 'Belum disimpan',\n 'card.saved': 'Tersimpan',\n 'card.saving': 'Menyimpan…',\n 'card.discard': 'Batalkan',\n 'card.save': 'Simpan',\n 'card.unavailable': 'Saluran konfigurasi sidebar-brand-text tidak tersedia. Silakan coba lagi nanti.',\n 'card.retry': 'Coba lagi',\n 'field.name.label': 'Nama merek',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Teks yang tampil di bilah sisi di samping logo. Mengganti teks bawaan \"DSH Local Build\".',\n 'field.revision.label': 'Lencana revisi',\n 'field.revision.placeholder': 'mis. v1.0.0 atau abc1234',\n 'field.revision.hint': 'Teks lencana kecil di samping nama merek. Kosongkan untuk menyembunyikan lencana.',\n },\n tr: {\n 'card.title': 'Kenar Çubuğu Marka Metni',\n 'card.intro': 'Kenar çubuğundaki marka adını ve sürüm rozetini özel metinle değiştirir.',\n 'card.unsaved': 'Kaydedilmedi',\n 'card.saved': 'Kaydedildi',\n 'card.saving': 'Kaydediliyor…',\n 'card.discard': 'Vazgeç',\n 'card.save': 'Kaydet',\n 'card.unavailable': 'sidebar-brand-text yapılandırma kanalı kullanılamıyor. Lütfen daha sonra tekrar deneyin.',\n 'card.retry': 'Tekrar dene',\n 'field.name.label': 'Marka adı',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Kenar çubuğunda logonun yanında gösterilen metin. Varsayılan \"DSH Local Build\" metnini değiştirir.',\n 'field.revision.label': 'Sürüm rozeti',\n 'field.revision.placeholder': 'ör. v1.0.0 veya abc1234',\n 'field.revision.hint': 'Marka adının yanındaki küçük rozet metni. Rozeti gizlemek için boş bırakın.',\n },\n vi: {\n 'card.title': 'Văn bản thương hiệu thanh bên',\n 'card.intro': 'Thay tên thương hiệu và huy hiệu phiên bản trên thanh bên bằng văn bản tùy chỉnh.',\n 'card.unsaved': 'Chưa lưu',\n 'card.saved': 'Đã lưu',\n 'card.saving': 'Đang lưu…',\n 'card.discard': 'Hủy bỏ',\n 'card.save': 'Lưu',\n 'card.unavailable': 'Kênh cấu hình sidebar-brand-text hiện không khả dụng. Vui lòng thử lại sau.',\n 'card.retry': 'Thử lại',\n 'field.name.label': 'Tên thương hiệu',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Văn bản hiển thị bên cạnh logo trên thanh bên. Thay thế văn bản mặc định \"DSH Local Build\".',\n 'field.revision.label': 'Huy hiệu phiên bản',\n 'field.revision.placeholder': 'ví dụ v1.0.0 hoặc abc1234',\n 'field.revision.hint': 'Văn bản huy hiệu nhỏ bên cạnh tên thương hiệu. Để trống để ẩn huy hiệu.',\n },\n th: {\n 'card.title': 'ข้อความแบรนด์ในแถบด้านข้าง',\n 'card.intro': 'แทนที่ชื่อแบรนด์และป้ายเวอร์ชันในแถบด้านข้างด้วยข้อความที่กำหนดเอง',\n 'card.unsaved': 'ยังไม่ได้บันทึก',\n 'card.saved': 'บันทึกแล้ว',\n 'card.saving': 'กำลังบันทึก…',\n 'card.discard': 'ยกเลิก',\n 'card.save': 'บันทึก',\n 'card.unavailable': 'ช่องการกำหนดค่า sidebar-brand-text ไม่พร้อมใช้งาน โปรดลองอีกครั้งในภายหลัง',\n 'card.retry': 'ลองอีกครั้ง',\n 'field.name.label': 'ชื่อแบรนด์',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'ข้อความที่แสดงในแถบด้านข้างถัดจากโลโก้ แทนที่ค่าเริ่มต้น \"DSH Local Build\"',\n 'field.revision.label': 'ป้ายเวอร์ชัน',\n 'field.revision.placeholder': 'เช่น v1.0.0 หรือ abc1234',\n 'field.revision.hint': 'ข้อความป้ายขนาดเล็กถัดจากชื่อแบรนด์ เว้นว่างไว้เพื่อซ่อนป้าย',\n },\n ru: {\n 'card.title': 'Текст бренда в боковой панели',\n 'card.intro': 'Заменяет название бренда и значок версии в боковой панели на собственный текст.',\n 'card.unsaved': 'Не сохранено',\n 'card.saved': 'Сохранено',\n 'card.saving': 'Сохранение…',\n 'card.discard': 'Отменить',\n 'card.save': 'Сохранить',\n 'card.unavailable': 'Канал настройки sidebar-brand-text недоступен. Повторите попытку позже.',\n 'card.retry': 'Повторить',\n 'field.name.label': 'Название бренда',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Текст рядом с логотипом в боковой панели. Заменяет значение по умолчанию «DSH Local Build».',\n 'field.revision.label': 'Значок версии',\n 'field.revision.placeholder': 'например, v1.0.0 или abc1234',\n 'field.revision.hint': 'Мелкий значок рядом с названием бренда. Оставьте пустым, чтобы скрыть значок.',\n },\n it: {\n 'card.title': 'Testo Brand nella Sidebar',\n 'card.intro': 'Sostituisce il nome del brand e il badge di revisione nella sidebar con un testo personalizzato.',\n 'card.unsaved': 'Non salvato',\n 'card.saved': 'Salvato',\n 'card.saving': 'Salvataggio…',\n 'card.discard': 'Annulla',\n 'card.save': 'Salva',\n 'card.unavailable': 'Il canale di configurazione sidebar-brand-text non è disponibile. Riprova più tardi.',\n 'card.retry': 'Riprova',\n 'field.name.label': 'Nome del brand',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Testo mostrato nella sidebar accanto al logo. Sostituisce il \"DSH Local Build\" predefinito.',\n 'field.revision.label': 'Badge di revisione',\n 'field.revision.placeholder': 'es. v1.0.0 o abc1234',\n 'field.revision.hint': 'Testo del badge accanto al nome del brand. Lascia vuoto per nascondere il badge.',\n },\n nl: {\n 'card.title': 'Merktekst in zijbalk',\n 'card.intro': 'Vervangt de merknaam en het revisiebadge in de zijbalk door aangepaste tekst.',\n 'card.unsaved': 'Niet opgeslagen',\n 'card.saved': 'Opgeslagen',\n 'card.saving': 'Opslaan…',\n 'card.discard': 'Verwijderen',\n 'card.save': 'Opslaan',\n 'card.unavailable': 'Het configuratiekanaal sidebar-brand-text is niet beschikbaar. Probeer het later opnieuw.',\n 'card.retry': 'Opnieuw proberen',\n 'field.name.label': 'Merknaam',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Tekst die in de zijbalk naast het logo wordt weergegeven. Vervangt de standaard \"DSH Local Build\".',\n 'field.revision.label': 'Revisiebadge',\n 'field.revision.placeholder': 'bv. v1.0.0 of abc1234',\n 'field.revision.hint': 'Kleine badgetekst naast de merknaam. Leeg laten om het badge te verbergen.',\n },\n sv: {\n 'card.title': 'Sidofältets varumärkestext',\n 'card.intro': 'Ersätter varumärkesnamnet och revisionsmärket i sidofältet med anpassad text.',\n 'card.unsaved': 'Ej sparat',\n 'card.saved': 'Sparat',\n 'card.saving': 'Sparar…',\n 'card.discard': 'Ignorera',\n 'card.save': 'Spara',\n 'card.unavailable': 'Konfigurationskanalen för sidebar-brand-text är inte tillgänglig. Försök igen senare.',\n 'card.retry': 'Försök igen',\n 'field.name.label': 'Varumärkesnamn',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Text som visas i sidofältet bredvid logotypen. Ersätter standardvärdet \"DSH Local Build\".',\n 'field.revision.label': 'Revisionsmärke',\n 'field.revision.placeholder': 't.ex. v1.0.0 eller abc1234',\n 'field.revision.hint': 'Liten märktext bredvid varumärkesnamnet. Lämna tomt för att dölja märket.',\n },\n pl: {\n 'card.title': 'Tekst marki na pasku bocznym',\n 'card.intro': 'Zastępuje nazwę marki i odznakę rewizji na pasku bocznym niestandardowym tekstem.',\n 'card.unsaved': 'Niezapisane',\n 'card.saved': 'Zapisano',\n 'card.saving': 'Zapisywanie…',\n 'card.discard': 'Odrzuć',\n 'card.save': 'Zapisz',\n 'card.unavailable': 'Kanał konfiguracji sidebar-brand-text jest niedostępny. Spróbuj ponownie później.',\n 'card.retry': 'Spróbuj ponownie',\n 'field.name.label': 'Nazwa marki',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Tekst wyświetlany na pasku bocznym obok logo. Zastępuje domyślny „DSH Local Build“.',\n 'field.revision.label': 'Odznaka rewizji',\n 'field.revision.placeholder': 'np. v1.0.0 lub abc1234',\n 'field.revision.hint': 'Mały tekst odznaki obok nazwy marki. Pozostaw puste, aby ukryć odznakę.',\n },\n 'zh-HK': {\n 'card.title': '側邊欄品牌文字',\n 'card.intro': '將側邊欄的品牌名稱與版本徽標替換為自訂文字。',\n 'card.unsaved': '未儲存',\n 'card.saved': '已儲存',\n 'card.saving': '儲存中…',\n 'card.discard': '放棄',\n 'card.save': '儲存',\n 'card.unavailable': '側邊欄品牌文字設定通道目前無法使用,請稍後重試。',\n 'card.retry': '重試',\n 'field.name.label': '品牌名稱',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '側邊欄 logo 右側顯示的文字。取代預設的「DSH Local Build」。',\n 'field.revision.label': '版本徽標',\n 'field.revision.placeholder': '例如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名稱右側的小徽標文字。留空則不顯示徽標。',\n },\n 'zh-TW': {\n 'card.title': '側邊欄品牌文字',\n 'card.intro': '將側邊欄的品牌名稱與版本徽標替換為自訂文字。',\n 'card.unsaved': '未儲存',\n 'card.saved': '已儲存',\n 'card.saving': '儲存中…',\n 'card.discard': '放棄',\n 'card.save': '儲存',\n 'card.unavailable': '側邊欄品牌文字設定通道目前無法使用,請稍後重試。',\n 'card.retry': '重試',\n 'field.name.label': '品牌名稱',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '側邊欄 logo 右側顯示的文字。取代預設的「DSH Local Build」。',\n 'field.revision.label': '版本徽標',\n 'field.revision.placeholder': '例如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名稱右側的小徽標文字。留空則不顯示徽標。',\n },\n 'zh-MO': {\n 'card.title': '側邊欄品牌文字',\n 'card.intro': '將側邊欄的品牌名稱與版本徽標替換為自訂文字。',\n 'card.unsaved': '未儲存',\n 'card.saved': '已儲存',\n 'card.saving': '儲存中…',\n 'card.discard': '放棄',\n 'card.save': '儲存',\n 'card.unavailable': '側邊欄品牌文字設定通道目前無法使用,請稍後重試。',\n 'card.retry': '重試',\n 'field.name.label': '品牌名稱',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '側邊欄 logo 右側顯示的文字。取代預設的「DSH Local Build」。',\n 'field.revision.label': '版本徽標',\n 'field.revision.placeholder': '例如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名稱右側的小徽標文字。留空則不顯示徽標。',\n },\n}","/** Shared config surface of the sidebar-brand-text plugin (host + client halves). */\n\n/**\n * The plugin's user-facing settings, persisted through the settings seam\n * under the `sidebar-brand-text` namespace in `$DSH_HOME/settings.yaml`.\n * The browser half reads these via the `/sbbt/api/get` HTTP route.\n */\nexport interface BrandTextConfig {\n /**\n * Brand name text shown in the sidebar's top-left brand row, beside the\n * mark slot. Replaces the shell's \"DSH Local Build\" fallback.\n */\n name: string\n /**\n * Revision badge text rendered beside the brand name. Empty string hides\n * the badge entirely. Replaces the shell's 7-character\n * `DSH_CLIENT_COMMIT_HASH` fallback.\n */\n revision: string\n}\n\n/** Runtime defaults applied when no config arrives (defensive only). */\nexport const DEFAULT_BRAND_TEXT_CONFIG: BrandTextConfig = {\n name: 'DSH Local Build',\n revision: '',\n}\n","/**\n * The `sidebar.brand.name` slot occupant — renders the configured brand\n * name text and optional revision badge.\n *\n * Reads from the shared `BrandTextSettingsController` store via\n * `useSnapshot`, so a save in the settings card is instantly reflected\n * here without a DOM event or RPC re-fetch.\n *\n * Replaces the shell's fallback (`DSH Local Build` + 7-character\n * `DSH_CLIENT_COMMIT_HASH` badge). The mark slot (`sidebar.brand.mark`)\n * is untouched: the fish logo stays unless another plugin (e.g.\n * `ui-brand-official`) replaces it.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/BrandText\n */\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { BrandTextConfig } from '../types.ts'\nimport { DEFAULT_BRAND_TEXT_CONFIG } from '../types.ts'\n\n/** Inject face: the selector hook bound to the shared controller store. */\nexport interface BrandTextInjected {\n readonly useSnapshot: SnapshotSelectorHook<BrandTextStateShell>\n}\n\n/** The slice of state the brand component reads. */\nexport interface BrandTextStateShell {\n draft: BrandTextConfig\n available: boolean\n}\n\n/** Full props: the slot's runtime share plus the plugin's inject face. */\nexport type BrandTextProps = PropsRuntime<'sidebar.brand.name'> & BrandTextInjected\n\n/**\n * Render the configured brand name and optional revision badge.\n *\n * While loading or on error, falls back to the shell defaults.\n * @param props - the `useSnapshot` inject face (plus the slot's runtime share, unused).\n * @returns the brand-name span and optional revision-badge span.\n */\nexport function BrandText({ useSnapshot }: BrandTextProps) {\n const state = useSnapshot((s) => s)\n const cfg: BrandTextConfig = state.available ? state.draft : DEFAULT_BRAND_TEXT_CONFIG\n\n return (\n <>\n <span className=\"sbbt-brand-name\">{cfg.name}</span>\n {cfg.revision !== '' ? (\n <span className=\"sbbt-build-revision\">{cfg.revision}</span>\n ) : null}\n </>\n )\n}\n","/**\n * BrandTextCard — the `settings.plugin.item` slot occupant.\n *\n * An expandable card (mirrors the ego-browser `EgoBrowserCard` pattern)\n * with two text inputs: brand name and revision badge. Reads/writes\n * through the shared `BrandTextSettingsController` which uses\n * `fetch('/sbbt/api/get')` and `fetch('/sbbt/api/set')`.\n *\n * Registered under the `settings.plugin.item` keyed slot with\n * `key: 'sidebar-brand-text'` — appears in the Plugin Config page\n * alongside the built-in cards.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/BrandTextCard\n */\nimport type { CSSProperties } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { BrandTextState } from './controller.ts'\n\n/** Inject face: controller + selector hook. */\nexport interface BrandTextCardInjected {\n readonly controller: {\n readonly load: () => Promise<void>\n readonly edit: (field: 'name' | 'revision', value: string) => void\n readonly discard: () => void\n readonly save: () => Promise<void>\n readonly toggle: () => void\n }\n readonly useSnapshot: SnapshotSelectorHook<BrandTextState>\n}\n\n/** Full props: locale seat + inject. */\nexport type BrandTextCardProps = PropsLocale<'dsh-plugin-sidebar-brand-text'> & BrandTextCardInjected\n\nconst cardStyle: CSSProperties = {\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.22))',\n background: 'var(--dsw-alias-bg-layer-3, transparent)',\n borderRadius: 12,\n listStyle: 'none',\n transition: 'border-color .16s, background .16s',\n}\n\nconst headerStyle: CSSProperties = {\n appearance: 'none',\n width: '100%',\n font: 'inherit',\n color: 'inherit',\n textAlign: 'left',\n cursor: 'pointer',\n background: 'transparent',\n border: 0,\n borderRadius: 12,\n alignItems: 'center',\n gap: 12,\n padding: '14px 16px',\n display: 'flex',\n}\n\nconst headTextStyle: CSSProperties = {\n flexDirection: 'column',\n flex: 1,\n gap: 4,\n minWidth: 0,\n display: 'flex',\n}\n\nconst nameStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary, inherit)',\n fontSize: 15,\n fontWeight: 600,\n lineHeight: 1.4,\n}\n\nconst descStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary, rgba(128,128,128,0.7))',\n fontSize: 13,\n lineHeight: 1.5,\n}\n\nconst pendingStyle: CSSProperties = {\n whiteSpace: 'nowrap',\n background: 'var(--dsw-alias-bg-module-platform, rgba(128,128,128,0.12))',\n color: 'var(--dsw-alias-label-secondary, inherit)',\n borderRadius: 999,\n flex: 'none',\n padding: '1px 8px',\n fontSize: 11,\n fontWeight: 500,\n lineHeight: '17px',\n}\n\nconst chevronStyle = (open: boolean): CSSProperties => ({\n color: 'var(--dsw-alias-label-tertiary, inherit)',\n flex: 'none',\n transition: 'transform .16s',\n display: 'inline-flex',\n alignItems: 'center',\n transform: open ? 'rotate(180deg)' : 'none',\n})\n\nconst bodyStyle: CSSProperties = {\n borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.22))',\n margin: '0 16px',\n padding: '12px 0 4px',\n}\n\nconst formStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n}\n\nconst fieldStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n}\n\nconst labelStyle: CSSProperties = {\n display: 'block',\n fontSize: 13,\n fontWeight: 500,\n color: 'var(--dsw-alias-label-primary, inherit)',\n}\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n padding: '6px 10px',\n fontSize: 13,\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.3))',\n background: 'var(--dsw-alias-bg-layer-3, transparent)',\n color: 'var(--dsw-alias-label-primary, inherit)',\n boxSizing: 'border-box',\n fontFamily: 'inherit',\n}\n\nconst hintStyle: CSSProperties = {\n fontSize: 12,\n color: 'var(--dsw-alias-label-tertiary, rgba(128,128,128,0.6))',\n margin: 0,\n lineHeight: 1.5,\n}\n\nconst footerStyle: CSSProperties = {\n borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.22))',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: 8,\n padding: '12px 0 4px',\n display: 'flex',\n}\n\nconst btnBase: CSSProperties = {\n appearance: 'none',\n font: 'inherit',\n cursor: 'pointer',\n border: '1px solid transparent',\n borderRadius: 8,\n padding: '5px 14px',\n fontSize: 13,\n fontWeight: 500,\n lineHeight: '20px',\n color: 'var(--dsw-alias-label-primary, inherit)',\n background: 'var(--dsw-alias-bg-module-platform, rgba(128,128,128,0.12))',\n transition: 'background .16s, opacity .16s',\n}\n\nconst noticeStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary, rgba(128,128,128,0.7))',\n margin: '0 0 8px',\n fontSize: 12,\n lineHeight: 1.5,\n}\n\nconst savedStyle: CSSProperties = {\n color: 'var(--dsw-alias-state-success-primary, #30d158)',\n margin: '0 0 12px',\n fontSize: 12,\n lineHeight: 1.5,\n}\n\nconst errorStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-error, #ff453a)',\n margin: '0 0 12px',\n fontSize: 12,\n lineHeight: 1.5,\n minWidth: 0,\n}\n\nconst CHEVRON_SVG = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>'\n\n/**\n * Render the sidebar-brand-text settings card.\n * @param props - locale + controller/useSnapshot inject.\n * @returns a `<li>` card element.\n */\nexport function BrandTextCard({ t, controller, useSnapshot }: BrandTextCardProps) {\n const state = useSnapshot((s) => s)\n if (state.status === 'idle') void controller.load()\n\n const degraded = state.status === 'ready' && !state.available\n const open = state._open || degraded\n const applyState = state.applyState ?? { kind: 'idle' }\n const saving = applyState.kind === 'saving'\n const saved = applyState.kind === 'saved'\n const errorText = applyState.kind === 'error' ? applyState.message : undefined\n const busy = !state.writable || saving\n\n const header = (\n <button\n type=\"button\"\n style={headerStyle}\n aria-expanded={open}\n aria-label={t('card.title')}\n onClick={() => { if (!degraded) controller.toggle() }}\n >\n <span style={headTextStyle}>\n <span style={nameStyle}>{t('card.title')}</span>\n <span style={descStyle}>{t('card.intro')}</span>\n </span>\n {state.dirty ? <span style={pendingStyle}>{t('card.unsaved')}</span> : null}\n <span style={chevronStyle(open)} dangerouslySetInnerHTML={{ __html: CHEVRON_SVG }} />\n </button>\n )\n\n let body: React.ReactNode = null\n if (open) {\n if (!state.available) {\n body = (\n <div style={bodyStyle}>\n <p style={noticeStyle} role=\"status\">{t('card.unavailable')}</p>\n <div style={footerStyle}>\n <button\n type=\"button\"\n style={btnBase}\n onClick={() => { void controller.load() }}\n >\n {t('card.retry')}\n </button>\n </div>\n </div>\n )\n } else {\n body = (\n <div style={bodyStyle}>\n {saved ? <p style={savedStyle} role=\"status\">{t('card.saved')}</p> : null}\n {errorText !== undefined ? <p style={errorStyle} role=\"status\">{errorText}</p> : null}\n <div style={formStyle}>\n <div style={fieldStyle}>\n <label style={labelStyle} htmlFor=\"sbbt-name\">{t('field.name.label')}</label>\n <input\n id=\"sbbt-name\"\n type=\"text\"\n style={inputStyle}\n value={state.draft.name}\n placeholder={t('field.name.placeholder')}\n disabled={busy}\n onChange={(e) => controller.edit('name', e.target.value)}\n />\n <p style={hintStyle}>{t('field.name.hint')}</p>\n </div>\n <div style={fieldStyle}>\n <label style={labelStyle} htmlFor=\"sbbt-revision\">{t('field.revision.label')}</label>\n <input\n id=\"sbbt-revision\"\n type=\"text\"\n style={inputStyle}\n value={state.draft.revision}\n placeholder={t('field.revision.placeholder')}\n disabled={busy}\n onChange={(e) => controller.edit('revision', e.target.value)}\n />\n <p style={hintStyle}>{t('field.revision.hint')}</p>\n </div>\n </div>\n <div style={footerStyle}>\n <button\n type=\"button\"\n style={{ ...btnBase, opacity: (!state.dirty || saving) ? 0.5 : 1 }}\n disabled={!state.dirty || saving}\n onClick={() => controller.discard()}\n >\n {t('card.discard')}\n </button>\n <button\n type=\"button\"\n style={{\n ...btnBase,\n background: 'var(--dsw-alias-brand-primary, #0a84ff)',\n color: 'var(--dsw-alias-bg-layer-1, #fff)',\n opacity: (!state.dirty || saving) ? 0.5 : 1,\n }}\n disabled={!state.dirty || saving}\n onClick={() => { void controller.save() }}\n >\n {saving ? t('card.saving') : t('card.save')}\n </button>\n </div>\n </div>\n )\n }\n }\n\n return (\n <li style={cardStyle}>\n {header}\n {open ? body : null}\n </li>\n )\n}\n","/**\n * `BrandTextSettingsController` — client-side state store for the\n * sidebar-brand-text config.\n *\n * Loads the config from the host's `/sbbt/api/get` route, stages edits,\n * and saves via `/sbbt/api/set`. The `sidebar.brand.name` slot occupant\n * and the `settings.plugin.item` card both read from the same store via\n * `bindSnapshotSelector`, so a save is instantly reflected in the sidebar\n * without a DOM event or page reload.\n *\n * Mirrors the ego-browser `EgoBrowserSettingsController` pattern.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/controller\n */\nimport { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport { DEFAULT_BRAND_TEXT_CONFIG, type BrandTextConfig } from '../types.ts'\n\n/** The controller's snapshot state. */\nexport interface BrandTextState {\n /** 'idle' | 'loading' | 'ready' */\n status: 'idle' | 'loading' | 'ready'\n /** True after a successful `/sbbt/api/get`; false when the route is unreachable. */\n available: boolean\n /** False when the settings service is absent (read-only). */\n writable: boolean\n /** Current draft values (edited by the card, read by the brand slot). */\n draft: BrandTextConfig\n /** True when the draft differs from the last-saved config. */\n dirty: boolean\n /** Apply lifecycle: 'idle' | 'saving' | 'saved' | 'error'. */\n applyState: { kind: 'idle' } | { kind: 'saving' } | { kind: 'saved' } | { kind: 'error', message: string }\n /** Card expand state (toggled by the card header button). */\n _open: boolean\n}\n\n/** Initial state before the first load. */\nfunction initialState(): BrandTextState {\n return {\n status: 'idle',\n available: false,\n writable: false,\n draft: { ...DEFAULT_BRAND_TEXT_CONFIG },\n dirty: false,\n applyState: { kind: 'idle' },\n _open: false,\n }\n}\n\n/**\n * Controller managing the brand-text config lifecycle.\n *\n * Constructed once in the client `apply()` and shared between the\n * `sidebar.brand.name` slot and the `settings.plugin.item` card.\n */\nexport class BrandTextSettingsController {\n readonly store: SnapshotStore<BrandTextState>\n loaded = false\n private generation = 0\n\n constructor() {\n this.store = createSnapshotStore<BrandTextState>(initialState())\n }\n\n /** Fetch the config from `/sbbt/api/get` and update the store. */\n async load(): Promise<void> {\n const gen = ++this.generation\n this.store.update((s) => { s.status = 'loading' })\n try {\n const res = await fetch('/sbbt/api/get', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: '{}',\n })\n if (!res.ok) {\n this.markUnavailable(gen)\n return\n }\n const parsed = await res.json().catch(() => null)\n if (gen !== this.generation) return\n if (!parsed || parsed.ok !== true || !parsed.value) {\n this.markUnavailable(gen)\n return\n }\n const config = parsed.value.config as BrandTextConfig | undefined\n this.loaded = true\n this.store.update((s) => {\n s.status = 'ready'\n s.available = true\n s.writable = true\n if (config) {\n s.draft = { name: config.name, revision: config.revision }\n }\n s.dirty = false\n s.applyState = { kind: 'idle' }\n })\n } catch {\n this.markUnavailable(gen)\n }\n }\n\n /** Stage an edit to a field (does not save). */\n edit(field: 'name' | 'revision', value: string): void {\n this.store.update((s) => {\n if (field === 'name') s.draft.name = value\n else s.draft.revision = value\n s.dirty = true\n s.applyState = { kind: 'idle' }\n })\n }\n\n /** Discard staged edits and reload from the host. */\n discard(): void {\n void this.load()\n }\n\n /** Save the staged draft via `/sbbt/api/set`. */\n async save(): Promise<void> {\n const gen = ++this.generation\n const snapshot = this.store.getSnapshot()\n if (!snapshot.dirty) return\n this.store.update((s) => { s.applyState = { kind: 'saving' } })\n try {\n const res = await fetch('/sbbt/api/set', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ patch: snapshot.draft }),\n })\n const parsed = await res.json().catch(() => null)\n if (gen !== this.generation) return\n if (!parsed || parsed.ok !== true || !parsed.value) {\n const message = parsed?.error?.message ?? 'Save failed'\n this.store.update((s) => { s.applyState = { kind: 'error', message } })\n return\n }\n const config = parsed.value.config as BrandTextConfig | undefined\n this.store.update((s) => {\n s.applyState = { kind: 'saved' }\n if (config) {\n s.draft = { name: config.name, revision: config.revision }\n }\n s.dirty = false\n })\n } catch (error) {\n if (gen !== this.generation) return\n const message = error instanceof Error ? error.message : String(error)\n this.store.update((s) => { s.applyState = { kind: 'error', message } })\n }\n }\n\n /** Toggle the card's expand state (mirrors ego-browser `controller.toggle()`). */\n toggle(): void {\n this.store.update((s) => { s._open = !s._open })\n }\n\n /** Mark the store as unavailable (route unreachable or settings service absent). */\n private markUnavailable(gen: number): void {\n if (gen !== this.generation) return\n this.store.update((s) => {\n s.status = 'ready'\n s.available = false\n s.writable = false\n })\n }\n}\n","/**\n * Inlined `bindSnapshotSelector` — rc.8 dropped this from\n * `@deepseek-ai/dsh-client-ui-renderer`'s package root, so business plugins\n * carry their own copy. Uses React 18's built-in `useSyncExternalStore`\n * with per-snapshot selector memoization via `useRef` (same approach as\n * the ego-browser plugin).\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/bindSnapshotSelector\n */\nimport { useRef, useSyncExternalStore } from 'react'\nimport type { HostObservable, SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\n\n/**\n * Bind a React selector hook to a {@link HostObservable} snapshot source.\n * @param source - the observable snapshot store.\n * @returns a `useSelector(sel, eq?)` hook.\n */\nexport function bindSnapshotSelector<T>(source: HostObservable<T>): SnapshotSelectorHook<T> {\n const subscribe = (fn: () => void): (() => void) => source.subscribe(fn)\n const getSnapshot = (): T => source.getSnapshot()\n return function useSelector<S>(sel: (s: T) => S): S {\n const snapshot = useSyncExternalStore(subscribe, getSnapshot)\n const prevSnapshotRef = useRef<T | undefined>(undefined)\n const prevSelectedRef = useRef<S | undefined>(undefined)\n if (prevSnapshotRef.current !== snapshot) {\n prevSnapshotRef.current = snapshot\n prevSelectedRef.current = sel(snapshot)\n }\n return prevSelectedRef.current as S\n }\n}\n","/**\n * Overrides `document.title` so the configured brand name replaces the\n * build-time `DSH_CLIENT_TITLE` literal that `DocumentTitle.tsx` writes.\n *\n * DSH's built-in `DocumentTitle` component (ui-renderer) subscribes to\n * `sessions.list` and writes `<session title> — <productTitle>` where\n * `productTitle` is the build-time `process.env.DSH_CLIENT_TITLE` literal\n * (fallback `'DSH Local Build'`). That literal is baked into the bundle at\n * build time, so no slot or runtime config can touch it — see\n * `ui-brand-official/README.md` (\"The browser title is independent\").\n *\n * This writer subscribes to the **same** `sessions.list` feed and to the\n * shared `BrandTextSettingsController` store. After `DocumentTitle`'s\n * `useEffect` writes the title, this writer's `queueMicrotask` callback\n * overwrites it with `<session title> — <configured brand>`. A\n * `MutationObserver` on `<title>` is the backstop for React 18 concurrent\n * re-renders that may run after the microtask.\n *\n * On dispose, all subscriptions and the observer are torn down, and\n * `DocumentTitle`'s own `useEffect` cleanup restores the build-time title.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/titleWriter\n */\nimport type { BrandTextConfig } from '../types.ts'\nimport { DEFAULT_BRAND_TEXT_CONFIG } from '../types.ts'\nimport type { BrandTextState } from './controller.ts'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\n\n/** Minimal face of `sessions.list` we depend on (ISessions.list slice). */\ninterface SessionListSnapshot {\n current: string | undefined\n byId: Record<string, { title?: string } | undefined>\n}\n\n/** Minimal face of the `sessions` service we depend on. */\ninterface SessionsLike {\n readonly list: {\n getSnapshot(): SessionListSnapshot\n subscribe(fn: () => void): () => void\n }\n}\n\n/** Disposer returned by {@link startTitleWriter}. */\nexport type TitleWriterDisposer = () => void\n\n/**\n * Start overriding `document.title` with the configured brand name.\n *\n * @param sessions - the cordis `sessions` service (read-only face).\n * @param store - the shared `BrandTextSettingsController` store; the title\n * updates when the config changes (card save) as well as when the current\n * session changes.\n * @returns a disposer that tears down all subscriptions and the observer.\n */\nexport function startTitleWriter(\n sessions: SessionsLike | undefined,\n store: SnapshotStore<BrandTextState>,\n): TitleWriterDisposer {\n if (sessions === undefined) return () => {}\n if (typeof document === 'undefined') return () => {}\n\n /** Compute the title we want, from the current session + brand config. */\n const computeTitle = (): string => {\n const state = store.getSnapshot()\n const cfg: BrandTextConfig = state.available ? state.draft : DEFAULT_BRAND_TEXT_CONFIG\n const list = sessions.list.getSnapshot()\n const id = list.current\n const sessionTitle = id === undefined ? undefined : list.byId[id]?.title\n return sessionTitle === undefined || sessionTitle === ''\n ? cfg.name\n : `${sessionTitle} — ${cfg.name}`\n }\n\n /** Write the computed title if it differs (avoids spurious observer fires). */\n const applyTitle = (): void => {\n const expected = computeTitle()\n if (document.title !== expected) document.title = expected\n }\n\n /** Deferred writer: runs after React's useEffect via microtask. */\n const deferredApply = (): void => { queueMicrotask(applyTitle) }\n\n const stopSessionSub = sessions.list.subscribe(deferredApply)\n const stopStoreSub = store.subscribe(deferredApply)\n\n let observer: MutationObserver | null = null\n const titleEl = document.querySelector('title')\n if (titleEl !== null) {\n observer = new MutationObserver(applyTitle)\n observer.observe(titleEl, { childList: true, subtree: true, characterData: true })\n }\n\n queueMicrotask(applyTitle)\n\n return () => {\n stopSessionSub()\n stopStoreSub()\n observer?.disconnect()\n observer = null\n }\n}\n","/**\n * Locale dictionaries for the `dsh-plugin-sidebar-brand-text` namespace.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/locales\n */\n\n/** The locale keys the settings card reads. */\nexport type BrandTextKey =\n | 'card.title'\n | 'card.intro'\n | 'card.unsaved'\n | 'card.saved'\n | 'card.saving'\n | 'card.discard'\n | 'card.save'\n | 'card.unavailable'\n | 'card.retry'\n | 'field.name.label'\n | 'field.name.placeholder'\n | 'field.name.hint'\n | 'field.revision.label'\n | 'field.revision.placeholder'\n | 'field.revision.hint'\n\n/** The locale namespace name; matches the `locale: NS` passed at slot register. */\nexport const NS = 'dsh-plugin-sidebar-brand-text'\n\n/** English dictionary. */\nexport const en: Record<BrandTextKey, string> = {\n 'card.title': 'Sidebar Brand Text',\n 'card.intro': 'Replace the sidebar brand name and revision badge with custom text.',\n 'card.unsaved': 'Unsaved',\n 'card.saved': 'Saved',\n 'card.saving': 'Saving…',\n 'card.discard': 'Discard',\n 'card.save': 'Save',\n 'card.unavailable': 'The sidebar-brand-text configuration channel is unavailable. Please retry later.',\n 'card.retry': 'Retry',\n 'field.name.label': 'Brand name',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Text shown in the sidebar next to the logo. Replaces the default \"DSH Local Build\".',\n 'field.revision.label': 'Revision badge',\n 'field.revision.placeholder': 'e.g. v1.0.0 or abc1234',\n 'field.revision.hint': 'Small badge text beside the brand name. Leave empty to hide the badge.',\n}\n\n/** Chinese dictionary. */\nexport const zh: Record<BrandTextKey, string> = {\n 'card.title': '侧边栏品牌文案',\n 'card.intro': '替换侧边栏左上角的品牌名与构建徽标文案。',\n 'card.unsaved': '未保存',\n 'card.saved': '已保存',\n 'card.saving': '保存中…',\n 'card.discard': '放弃',\n 'card.save': '保存',\n 'card.unavailable': '侧边栏品牌文案配置通道不可用,请稍后重试。',\n 'card.retry': '重试',\n 'field.name.label': '品牌名称',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '侧边栏 logo 右侧显示的文案。替换默认的「DSH Local Build」。',\n 'field.revision.label': '版本徽标',\n 'field.revision.placeholder': '如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名右侧的小徽标文案。留空则不显示徽标。',\n}\n","/**\n * One scoped stylesheet injected for the lifetime of the client activation.\n *\n * The shell's `sidebar.brand.name` fallback renders two CSS-Module-hashed\n * spans (`.fallbackBrandName` + `.buildRevision`); those class names are\n * not stable across builds and not addressable from outside the sidebar\n * package. This plugin ships its own class names with the same visual\n * intent, all colors and typography drawn from the shared `--dsw-*`\n * tokens (never literals) so the badge tracks the active theme.\n *\n * The parent `.brandName` span (inline-flex, gap: 6px, font-size: 18px,\n * font-weight: 600) is owned by the sidebar shell and wraps whatever the\n * slot occupant returns, so this stylesheet only needs to style the two\n * child spans.\n */\nexport const CSS = `\n.sbbt-brand-name {\n font-size: 17px;\n letter-spacing: 0px;\n white-space: nowrap;\n}\n\n.sbbt-build-revision {\n display: inline-flex;\n align-items: center;\n height: 16px;\n padding: 0 4px;\n border-radius: 3px;\n color: var(--dsw-alias-label-primary-inverted);\n background: var(--dsw-alias-label-primary);\n font-family: var(--ds-font-family-code);\n font-size: 8px;\n font-weight: 500;\n line-height: 16px;\n}\n`\n\n/**\n * Install the stylesheet and return its disposer.\n * @returns a cleanup function that removes the injected `<style>` tag.\n */\nexport function installStyles(): () => void {\n if (typeof document === 'undefined') return () => {}\n const style = document.createElement('style')\n style.setAttribute('data-sidebar-brand-text-style', '')\n style.textContent = CSS\n document.head.appendChild(style)\n return () => { style.remove() }\n}\n","/**\n * sidebar-brand-text — browser half.\n *\n * Two registrations:\n * - `settings.plugin.item` keyed slot (key `sidebar-brand-text`) — a card\n * in the Plugin Config page with two text inputs (name + revision).\n * Reads/writes through the `/sbbt/api` HTTP route via the shared\n * `BrandTextSettingsController`.\n * - `sidebar.brand.name` single slot — renders the configured brand name\n * text and optional revision badge. Reads from the same controller\n * store via `useSnapshot`, so a save in the card is instantly\n * reflected in the sidebar.\n *\n * The mark slot (`sidebar.brand.mark`) is deliberately NOT registered:\n * the fish logo stays in place unless another plugin (e.g.\n * `ui-brand-official`) replaces it.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { dicts } from './dictionaries.ts'\nimport { BrandText, type BrandTextInjected } from './BrandText.tsx'\nimport { BrandTextCard, type BrandTextCardInjected } from './BrandTextCard.tsx'\nimport { BrandTextSettingsController } from './controller.ts'\nimport { bindSnapshotSelector } from './bindSnapshotSelector.ts'\nimport { startTitleWriter } from './titleWriter.ts'\nimport { en, NS, zh, type BrandTextKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\n\n/** Structural view of the `ctx.betterLocale` service (published by dsh-plugin-better-locale). */\ninterface BetterLocaleStoreLike {\n register(ns: string, dicts: Record<string, Record<string, string>>): () => void\n}\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The settings card labels. */\n 'dsh-plugin-sidebar-brand-text': BrandTextKey\n }\n}\n\n/** Required services: slots + locale + sessions (sessions drives the title writer). */\nexport const inject = ['slots', 'locale', 'sessions']\n\n/**\n * Client plugin body: register the brand-name slot occupant, the settings\n * card, the locale dictionary, and the stylesheet.\n *\n * A single `BrandTextSettingsController` is shared between the card and\n * the brand text so a save is instantly reflected in the sidebar.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'sidebar-brand-text: dictionaries')\n ctx.effect(() => {\n let dispose: (() => void) | undefined\n const sync = (): void => {\n dispose?.()\n dispose = undefined\n const store = ctx.get('betterLocale') as BetterLocaleStoreLike | undefined\n if (store !== undefined) {\n dispose = store.register(NS, dicts)\n }\n }\n sync()\n const unsubscribe = ctx.locale.subscribe(sync)\n return () => {\n unsubscribe()\n dispose?.()\n }\n }, 'dsh-plugin-sidebar-brand-text: better-locale override dicts')\n ctx.effect(installStyles, 'sidebar-brand-text: styles')\n\n const controller = new BrandTextSettingsController()\n const useSnapshot = bindSnapshotSelector(controller.store)\n\n void controller.load()\n\n ctx.effect(() => startTitleWriter(ctx.sessions, controller.store), 'sidebar-brand-text: document.title override')\n\n const brandInjected = (): BrandTextInjected => ({ useSnapshot })\n ctx.slots.inject('sidebar.brand.name', () =>\n ctx.slots.register(\n {\n name: 'sidebar.brand.name',\n inject: brandInjected,\n },\n BrandText,\n ),\n )\n\n const cardInjected = (): BrandTextCardInjected => ({ controller, useSnapshot })\n ctx.slots.inject('settings.plugin.item', function* () {\n yield ctx.slots.register(\n {\n name: 'settings.plugin.item',\n key: 'sidebar-brand-text',\n locale: NS,\n inject: cardInjected,\n },\n BrandTextCard,\n )\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["dicts: Record<string, Record<BrandTextKey, string>>","DEFAULT_BRAND_TEXT_CONFIG: BrandTextConfig","cfg: BrandTextConfig","cardStyle: CSSProperties","headerStyle: CSSProperties","headTextStyle: CSSProperties","nameStyle: CSSProperties","descStyle: CSSProperties","pendingStyle: CSSProperties","bodyStyle: CSSProperties","formStyle: CSSProperties","fieldStyle: CSSProperties","labelStyle: CSSProperties","inputStyle: CSSProperties","hintStyle: CSSProperties","footerStyle: CSSProperties","btnBase: CSSProperties","noticeStyle: CSSProperties","savedStyle: CSSProperties","errorStyle: CSSProperties","body: React.ReactNode","cfg: BrandTextConfig","observer: MutationObserver | null","en: Record<BrandTextKey, string>","zh: Record<BrandTextKey, string>","dispose: (() => void) | undefined"],"sources":["../src/client/dictionaries.ts","../src/types.ts","../src/client/BrandText.tsx","../src/client/BrandTextCard.tsx","../src/client/controller.ts","../src/client/bindSnapshotSelector.ts","../src/client/titleWriter.ts","../src/client/locales.ts","../src/client/styles.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Override dictionaries for the `dsh-plugin-sidebar-brand-text` namespace,\n * registered with the better-locale override store (`ctx.betterLocale`)\n * when that plugin is installed. Keyed by locale id; every dictionary\n * covers the same keys as the native zh/en copy in `locales.ts`.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/dictionaries\n */\n\nimport type { BrandTextKey } from './locales.ts'\n\n/**\n * Locale-id keyed override dictionaries, one full copy per language.\n * The dict shape matches `BetterLocaleStore.register(ns, dicts)` where\n * `dicts` is `Record<localeId, Record<key, string>>`.\n */\nexport const dicts: Record<string, Record<BrandTextKey, string>> = {\n ja: {\n 'card.title': 'サイドバーのブランドテキスト',\n 'card.intro': 'サイドバーのブランド名とリビジョンバッジをカスタムテキストに置き換えます。',\n 'card.unsaved': '未保存',\n 'card.saved': '保存済み',\n 'card.saving': '保存中…',\n 'card.discard': '破棄',\n 'card.save': '保存',\n 'card.unavailable': 'サイドバー・ブランドテキストの設定チャンネルを利用できません。後でもう一度お試しください。',\n 'card.retry': '再試行',\n 'field.name.label': 'ブランド名',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'サイドバーでロゴの右隣に表示されるテキスト。既定の「DSH Local Build」を置き換えます。',\n 'field.revision.label': 'リビジョンバッジ',\n 'field.revision.placeholder': '例:v1.0.0 または abc1234',\n 'field.revision.hint': 'ブランド名の右隣に表示される小さなバッジテキスト。空にするとバッジを非表示にします。',\n },\n de: {\n 'card.title': 'Seitenleisten-Brand-Text',\n 'card.intro': 'Ersetzt den Markennamen und das Revisions-Abzeichen in der Seitenleiste durch benutzerdefinierten Text.',\n 'card.unsaved': 'Nicht gespeichert',\n 'card.saved': 'Gespeichert',\n 'card.saving': 'Wird gespeichert…',\n 'card.discard': 'Verwerfen',\n 'card.save': 'Speichern',\n 'card.unavailable': 'Der Konfigurationskanal „sidebar-brand-text“ ist derzeit nicht verfügbar. Versuchen Sie es später erneut.',\n 'card.retry': 'Erneut versuchen',\n 'field.name.label': 'Markenname',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Text neben dem Logo in der Seitenleiste. Ersetzt den Standardwert „DSH Local Build“.',\n 'field.revision.label': 'Revisions-Abzeichen',\n 'field.revision.placeholder': 'z. B. v1.0.0 oder abc1234',\n 'field.revision.hint': 'Kleiner Abzeichentext neben dem Markennamen. Leer lassen, um das Abzeichen auszublenden.',\n },\n fr: {\n 'card.title': 'Texte de marque de la barre latérale',\n 'card.intro': 'Remplace le nom de la marque et le badge de révision de la barre latérale par un texte personnalisé.',\n 'card.unsaved': 'Non enregistré',\n 'card.saved': 'Enregistré',\n 'card.saving': 'Enregistrement…',\n 'card.discard': 'Annuler',\n 'card.save': 'Enregistrer',\n 'card.unavailable': 'Le canal de configuration sidebar-brand-text est indisponible. Veuillez réessayer plus tard.',\n 'card.retry': 'Réessayer',\n 'field.name.label': 'Nom de marque',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Texte affiché dans la barre latérale à côté du logo. Remplace le « DSH Local Build » par défaut.',\n 'field.revision.label': 'Badge de révision',\n 'field.revision.placeholder': 'p. ex. v1.0.0 ou abc1234',\n 'field.revision.hint': 'Petit badge à côté du nom de la marque. Laisser vide pour masquer le badge.',\n },\n pt: {\n 'card.title': 'Texto da Marca na Barra Lateral',\n 'card.intro': 'Substitui o nome da marca e o selo de revisão da barra lateral por texto personalizado.',\n 'card.unsaved': 'Não salvo',\n 'card.saved': 'Salvo',\n 'card.saving': 'Salvando…',\n 'card.discard': 'Descartar',\n 'card.save': 'Salvar',\n 'card.unavailable': 'O canal de configuração do sidebar-brand-text está indisponível. Tente novamente mais tarde.',\n 'card.retry': 'Tentar novamente',\n 'field.name.label': 'Nome da marca',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Texto exibido na barra lateral ao lado do logotipo. Substitui o padrão \"DSH Local Build\".',\n 'field.revision.label': 'Selo de revisão',\n 'field.revision.placeholder': 'por exemplo, v1.0.0 ou abc1234',\n 'field.revision.hint': 'Texto pequeno ao lado do nome da marca. Deixe vazio para ocultar o selo.',\n },\n ko: {\n 'card.title': '사이드바 브랜드 텍스트',\n 'card.intro': '사이드바의 브랜드 이름과 리비전 배지를 사용자 지정 텍스트로 바꿉니다.',\n 'card.unsaved': '저장 안 됨',\n 'card.saved': '저장됨',\n 'card.saving': '저장 중…',\n 'card.discard': '취소',\n 'card.save': '저장',\n 'card.unavailable': 'sidebar-brand-text 구성 채널을 사용할 수 없습니다. 나중에 다시 시도하세요.',\n 'card.retry': '다시 시도',\n 'field.name.label': '브랜드 이름',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '사이드바에서 로고 옆에 표시되는 텍스트입니다. 기본값인 \"DSH Local Build\"를 대체합니다.',\n 'field.revision.label': '리비전 배지',\n 'field.revision.placeholder': '예: v1.0.0 또는 abc1234',\n 'field.revision.hint': '브랜드 이름 옆에 표시되는 작은 배지 텍스트입니다. 비워 두면 배지가 표시되지 않습니다.',\n },\n ar: {\n 'card.title': 'نص العلامة في الشريط الجانبي',\n 'card.intro': 'استبدل اسم العلامة وشارة المراجعة في الشريط الجانبي بنص مخصص.',\n 'card.unsaved': 'غير محفوظ',\n 'card.saved': 'محفوظ',\n 'card.saving': 'جارٍ الحفظ…',\n 'card.discard': 'تجاهل',\n 'card.save': 'حفظ',\n 'card.unavailable': 'قناة إعدادات نص العلامة الجانبية غير متاحة. يرجى المحاولة لاحقًا.',\n 'card.retry': 'إعادة المحاولة',\n 'field.name.label': 'اسم العلامة',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'النص المعروض في الشريط الجانبي بجانب الشعار. يستبدل النص الافتراضي «DSH Local Build».',\n 'field.revision.label': 'شارة المراجعة',\n 'field.revision.placeholder': 'مثل v1.0.0 أو abc1234',\n 'field.revision.hint': 'نص الشارة الصغيرة بجانب اسم العلامة. اتركه فارغًا لإخفاء الشارة.',\n },\n hi: {\n 'card.title': 'साइडबार ब्रांड टेक्स्ट',\n 'card.intro': 'साइडबार का ब्रांड नाम और रिवीज़न बैज कस्टम टेक्स्ट से बदलें।',\n 'card.unsaved': 'सहेजा नहीं गया',\n 'card.saved': 'सहेजा गया',\n 'card.saving': 'सहेजा जा रहा है…',\n 'card.discard': 'छोड़ें',\n 'card.save': 'सहेजें',\n 'card.unavailable': 'sidebar-brand-text कॉन्फ़िगरेशन चैनल उपलब्ध नहीं है। कृपया बाद में पुनः प्रयास करें।',\n 'card.retry': 'पुनः प्रयास करें',\n 'field.name.label': 'ब्रांड नाम',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'साइडबार में लोगो के बगल में दिखाया जाने वाला टेक्स्ट। डिफ़ॉल्ट \"DSH Local Build\" को बदलता है।',\n 'field.revision.label': 'रिवीज़न बैज',\n 'field.revision.placeholder': 'जैसे v1.0.0 या abc1234',\n 'field.revision.hint': 'ब्रांड नाम के बगल में छोटा बैज टेक्स्ट। बैज छिपाने के लिए खाली छोड़ें।',\n },\n id: {\n 'card.title': 'Teks Merek Bilah Sisi',\n 'card.intro': 'Ganti nama merek dan lencana revisi di bilah sisi dengan teks khusus.',\n 'card.unsaved': 'Belum disimpan',\n 'card.saved': 'Tersimpan',\n 'card.saving': 'Menyimpan…',\n 'card.discard': 'Batalkan',\n 'card.save': 'Simpan',\n 'card.unavailable': 'Saluran konfigurasi sidebar-brand-text tidak tersedia. Silakan coba lagi nanti.',\n 'card.retry': 'Coba lagi',\n 'field.name.label': 'Nama merek',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Teks yang tampil di bilah sisi di samping logo. Mengganti teks bawaan \"DSH Local Build\".',\n 'field.revision.label': 'Lencana revisi',\n 'field.revision.placeholder': 'mis. v1.0.0 atau abc1234',\n 'field.revision.hint': 'Teks lencana kecil di samping nama merek. Kosongkan untuk menyembunyikan lencana.',\n },\n tr: {\n 'card.title': 'Kenar Çubuğu Marka Metni',\n 'card.intro': 'Kenar çubuğundaki marka adını ve sürüm rozetini özel metinle değiştirir.',\n 'card.unsaved': 'Kaydedilmedi',\n 'card.saved': 'Kaydedildi',\n 'card.saving': 'Kaydediliyor…',\n 'card.discard': 'Vazgeç',\n 'card.save': 'Kaydet',\n 'card.unavailable': 'sidebar-brand-text yapılandırma kanalı kullanılamıyor. Lütfen daha sonra tekrar deneyin.',\n 'card.retry': 'Tekrar dene',\n 'field.name.label': 'Marka adı',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Kenar çubuğunda logonun yanında gösterilen metin. Varsayılan \"DSH Local Build\" metnini değiştirir.',\n 'field.revision.label': 'Sürüm rozeti',\n 'field.revision.placeholder': 'ör. v1.0.0 veya abc1234',\n 'field.revision.hint': 'Marka adının yanındaki küçük rozet metni. Rozeti gizlemek için boş bırakın.',\n },\n vi: {\n 'card.title': 'Văn bản thương hiệu thanh bên',\n 'card.intro': 'Thay tên thương hiệu và huy hiệu phiên bản trên thanh bên bằng văn bản tùy chỉnh.',\n 'card.unsaved': 'Chưa lưu',\n 'card.saved': 'Đã lưu',\n 'card.saving': 'Đang lưu…',\n 'card.discard': 'Hủy bỏ',\n 'card.save': 'Lưu',\n 'card.unavailable': 'Kênh cấu hình sidebar-brand-text hiện không khả dụng. Vui lòng thử lại sau.',\n 'card.retry': 'Thử lại',\n 'field.name.label': 'Tên thương hiệu',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Văn bản hiển thị bên cạnh logo trên thanh bên. Thay thế văn bản mặc định \"DSH Local Build\".',\n 'field.revision.label': 'Huy hiệu phiên bản',\n 'field.revision.placeholder': 'ví dụ v1.0.0 hoặc abc1234',\n 'field.revision.hint': 'Văn bản huy hiệu nhỏ bên cạnh tên thương hiệu. Để trống để ẩn huy hiệu.',\n },\n th: {\n 'card.title': 'ข้อความแบรนด์ในแถบด้านข้าง',\n 'card.intro': 'แทนที่ชื่อแบรนด์และป้ายเวอร์ชันในแถบด้านข้างด้วยข้อความที่กำหนดเอง',\n 'card.unsaved': 'ยังไม่ได้บันทึก',\n 'card.saved': 'บันทึกแล้ว',\n 'card.saving': 'กำลังบันทึก…',\n 'card.discard': 'ยกเลิก',\n 'card.save': 'บันทึก',\n 'card.unavailable': 'ช่องการกำหนดค่า sidebar-brand-text ไม่พร้อมใช้งาน โปรดลองอีกครั้งในภายหลัง',\n 'card.retry': 'ลองอีกครั้ง',\n 'field.name.label': 'ชื่อแบรนด์',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'ข้อความที่แสดงในแถบด้านข้างถัดจากโลโก้ แทนที่ค่าเริ่มต้น \"DSH Local Build\"',\n 'field.revision.label': 'ป้ายเวอร์ชัน',\n 'field.revision.placeholder': 'เช่น v1.0.0 หรือ abc1234',\n 'field.revision.hint': 'ข้อความป้ายขนาดเล็กถัดจากชื่อแบรนด์ เว้นว่างไว้เพื่อซ่อนป้าย',\n },\n ru: {\n 'card.title': 'Текст бренда в боковой панели',\n 'card.intro': 'Заменяет название бренда и значок версии в боковой панели на собственный текст.',\n 'card.unsaved': 'Не сохранено',\n 'card.saved': 'Сохранено',\n 'card.saving': 'Сохранение…',\n 'card.discard': 'Отменить',\n 'card.save': 'Сохранить',\n 'card.unavailable': 'Канал настройки sidebar-brand-text недоступен. Повторите попытку позже.',\n 'card.retry': 'Повторить',\n 'field.name.label': 'Название бренда',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Текст рядом с логотипом в боковой панели. Заменяет значение по умолчанию «DSH Local Build».',\n 'field.revision.label': 'Значок версии',\n 'field.revision.placeholder': 'например, v1.0.0 или abc1234',\n 'field.revision.hint': 'Мелкий значок рядом с названием бренда. Оставьте пустым, чтобы скрыть значок.',\n },\n it: {\n 'card.title': 'Testo Brand nella Sidebar',\n 'card.intro': 'Sostituisce il nome del brand e il badge di revisione nella sidebar con un testo personalizzato.',\n 'card.unsaved': 'Non salvato',\n 'card.saved': 'Salvato',\n 'card.saving': 'Salvataggio…',\n 'card.discard': 'Annulla',\n 'card.save': 'Salva',\n 'card.unavailable': 'Il canale di configurazione sidebar-brand-text non è disponibile. Riprova più tardi.',\n 'card.retry': 'Riprova',\n 'field.name.label': 'Nome del brand',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Testo mostrato nella sidebar accanto al logo. Sostituisce il \"DSH Local Build\" predefinito.',\n 'field.revision.label': 'Badge di revisione',\n 'field.revision.placeholder': 'es. v1.0.0 o abc1234',\n 'field.revision.hint': 'Testo del badge accanto al nome del brand. Lascia vuoto per nascondere il badge.',\n },\n nl: {\n 'card.title': 'Merktekst in zijbalk',\n 'card.intro': 'Vervangt de merknaam en het revisiebadge in de zijbalk door aangepaste tekst.',\n 'card.unsaved': 'Niet opgeslagen',\n 'card.saved': 'Opgeslagen',\n 'card.saving': 'Opslaan…',\n 'card.discard': 'Verwijderen',\n 'card.save': 'Opslaan',\n 'card.unavailable': 'Het configuratiekanaal sidebar-brand-text is niet beschikbaar. Probeer het later opnieuw.',\n 'card.retry': 'Opnieuw proberen',\n 'field.name.label': 'Merknaam',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Tekst die in de zijbalk naast het logo wordt weergegeven. Vervangt de standaard \"DSH Local Build\".',\n 'field.revision.label': 'Revisiebadge',\n 'field.revision.placeholder': 'bv. v1.0.0 of abc1234',\n 'field.revision.hint': 'Kleine badgetekst naast de merknaam. Leeg laten om het badge te verbergen.',\n },\n sv: {\n 'card.title': 'Sidofältets varumärkestext',\n 'card.intro': 'Ersätter varumärkesnamnet och revisionsmärket i sidofältet med anpassad text.',\n 'card.unsaved': 'Ej sparat',\n 'card.saved': 'Sparat',\n 'card.saving': 'Sparar…',\n 'card.discard': 'Ignorera',\n 'card.save': 'Spara',\n 'card.unavailable': 'Konfigurationskanalen för sidebar-brand-text är inte tillgänglig. Försök igen senare.',\n 'card.retry': 'Försök igen',\n 'field.name.label': 'Varumärkesnamn',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Text som visas i sidofältet bredvid logotypen. Ersätter standardvärdet \"DSH Local Build\".',\n 'field.revision.label': 'Revisionsmärke',\n 'field.revision.placeholder': 't.ex. v1.0.0 eller abc1234',\n 'field.revision.hint': 'Liten märktext bredvid varumärkesnamnet. Lämna tomt för att dölja märket.',\n },\n pl: {\n 'card.title': 'Tekst marki na pasku bocznym',\n 'card.intro': 'Zastępuje nazwę marki i odznakę rewizji na pasku bocznym niestandardowym tekstem.',\n 'card.unsaved': 'Niezapisane',\n 'card.saved': 'Zapisano',\n 'card.saving': 'Zapisywanie…',\n 'card.discard': 'Odrzuć',\n 'card.save': 'Zapisz',\n 'card.unavailable': 'Kanał konfiguracji sidebar-brand-text jest niedostępny. Spróbuj ponownie później.',\n 'card.retry': 'Spróbuj ponownie',\n 'field.name.label': 'Nazwa marki',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Tekst wyświetlany na pasku bocznym obok logo. Zastępuje domyślny „DSH Local Build“.',\n 'field.revision.label': 'Odznaka rewizji',\n 'field.revision.placeholder': 'np. v1.0.0 lub abc1234',\n 'field.revision.hint': 'Mały tekst odznaki obok nazwy marki. Pozostaw puste, aby ukryć odznakę.',\n },\n 'zh-HK': {\n 'card.title': '側邊欄品牌文字',\n 'card.intro': '將側邊欄的品牌名稱與版本徽標替換為自訂文字。',\n 'card.unsaved': '未儲存',\n 'card.saved': '已儲存',\n 'card.saving': '儲存中…',\n 'card.discard': '放棄',\n 'card.save': '儲存',\n 'card.unavailable': '側邊欄品牌文字設定通道目前無法使用,請稍後重試。',\n 'card.retry': '重試',\n 'field.name.label': '品牌名稱',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '側邊欄 logo 右側顯示的文字。取代預設的「DSH Local Build」。',\n 'field.revision.label': '版本徽標',\n 'field.revision.placeholder': '例如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名稱右側的小徽標文字。留空則不顯示徽標。',\n },\n 'zh-TW': {\n 'card.title': '側邊欄品牌文字',\n 'card.intro': '將側邊欄的品牌名稱與版本徽標替換為自訂文字。',\n 'card.unsaved': '未儲存',\n 'card.saved': '已儲存',\n 'card.saving': '儲存中…',\n 'card.discard': '放棄',\n 'card.save': '儲存',\n 'card.unavailable': '側邊欄品牌文字設定通道目前無法使用,請稍後重試。',\n 'card.retry': '重試',\n 'field.name.label': '品牌名稱',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '側邊欄 logo 右側顯示的文字。取代預設的「DSH Local Build」。',\n 'field.revision.label': '版本徽標',\n 'field.revision.placeholder': '例如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名稱右側的小徽標文字。留空則不顯示徽標。',\n },\n 'zh-MO': {\n 'card.title': '側邊欄品牌文字',\n 'card.intro': '將側邊欄的品牌名稱與版本徽標替換為自訂文字。',\n 'card.unsaved': '未儲存',\n 'card.saved': '已儲存',\n 'card.saving': '儲存中…',\n 'card.discard': '放棄',\n 'card.save': '儲存',\n 'card.unavailable': '側邊欄品牌文字設定通道目前無法使用,請稍後重試。',\n 'card.retry': '重試',\n 'field.name.label': '品牌名稱',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '側邊欄 logo 右側顯示的文字。取代預設的「DSH Local Build」。',\n 'field.revision.label': '版本徽標',\n 'field.revision.placeholder': '例如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名稱右側的小徽標文字。留空則不顯示徽標。',\n },\n}","/** Shared config surface of the sidebar-brand-text plugin (host + client halves). */\n\n/**\n * The plugin's user-facing settings, persisted through the settings seam\n * under the `sidebar-brand-text` namespace in `$DSH_HOME/settings.yaml`.\n * The browser half reads these via the `/sbbt/api/get` HTTP route.\n */\nexport interface BrandTextConfig {\n /**\n * Brand name text shown in the sidebar's top-left brand row, beside the\n * mark slot. Replaces the shell's \"DSH Local Build\" fallback.\n */\n name: string\n /**\n * Revision badge text rendered beside the brand name. Empty string hides\n * the badge entirely. Replaces the shell's 7-character\n * `DSH_CLIENT_COMMIT_HASH` fallback.\n */\n revision: string\n}\n\n/** Runtime defaults applied when no config arrives (defensive only). */\nexport const DEFAULT_BRAND_TEXT_CONFIG: BrandTextConfig = {\n name: 'DSH Local Build',\n revision: '',\n}\n","/**\n * The `sidebar.brand.name` slot occupant — renders the configured brand\n * name text and optional revision badge.\n *\n * Reads from the shared `BrandTextSettingsController` store via\n * `useSnapshot`, so a save in the settings card is instantly reflected\n * here without a DOM event or RPC re-fetch.\n *\n * Replaces the shell's fallback (`DSH Local Build` + 7-character\n * `DSH_CLIENT_COMMIT_HASH` badge). The mark slot (`sidebar.brand.mark`)\n * is untouched: the fish logo stays unless another plugin (e.g.\n * `ui-brand-official`) replaces it.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/BrandText\n */\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { BrandTextConfig } from '../types.ts'\nimport { DEFAULT_BRAND_TEXT_CONFIG } from '../types.ts'\n\n/** Inject face: the selector hook bound to the shared controller store. */\nexport interface BrandTextInjected {\n readonly useSnapshot: SnapshotSelectorHook<BrandTextStateShell>\n}\n\n/** The slice of state the brand component reads. */\nexport interface BrandTextStateShell {\n draft: BrandTextConfig\n available: boolean\n}\n\n/** Full props: the slot's runtime share plus the plugin's inject face. */\nexport type BrandTextProps = PropsRuntime<'sidebar.brand.name'> & BrandTextInjected\n\n/**\n * Render the configured brand name and optional revision badge.\n *\n * While loading or on error, falls back to the shell defaults.\n * @param props - the `useSnapshot` inject face (plus the slot's runtime share, unused).\n * @returns the brand-name span and optional revision-badge span.\n */\nexport function BrandText({ useSnapshot }: BrandTextProps) {\n const state = useSnapshot((s) => s)\n const cfg: BrandTextConfig = state.available ? state.draft : DEFAULT_BRAND_TEXT_CONFIG\n\n return (\n <>\n <span className=\"sbbt-brand-name\">{cfg.name}</span>\n {cfg.revision !== '' ? (\n <span className=\"sbbt-build-revision\">{cfg.revision}</span>\n ) : null}\n </>\n )\n}\n","/**\n * BrandTextCard — the `settings.plugin.item` slot occupant.\n *\n * An expandable card (mirrors the ego-browser `EgoBrowserCard` pattern)\n * with two text inputs: brand name and revision badge. Reads/writes\n * through the shared `BrandTextSettingsController` which uses\n * `fetch('/sbbt/api/get')` and `fetch('/sbbt/api/set')`.\n *\n * Registered under the `settings.plugin.item` keyed slot with\n * `key: 'sidebar-brand-text'` — appears in the Plugin Config page\n * alongside the built-in cards.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/BrandTextCard\n */\nimport type { CSSProperties } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { BrandTextState } from './controller.ts'\n\n/** Inject face: controller + selector hook. */\nexport interface BrandTextCardInjected {\n readonly controller: {\n readonly load: () => Promise<void>\n readonly edit: (field: 'name' | 'revision', value: string) => void\n readonly discard: () => void\n readonly save: () => Promise<void>\n readonly toggle: () => void\n }\n readonly useSnapshot: SnapshotSelectorHook<BrandTextState>\n}\n\n/** Full props: locale seat + inject. */\nexport type BrandTextCardProps = PropsLocale<'dsh-plugin-sidebar-brand-text'> & BrandTextCardInjected\n\nconst cardStyle: CSSProperties = {\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.22))',\n background: 'var(--dsw-alias-bg-layer-3, transparent)',\n borderRadius: 12,\n listStyle: 'none',\n transition: 'border-color .16s, background .16s',\n}\n\nconst headerStyle: CSSProperties = {\n appearance: 'none',\n width: '100%',\n font: 'inherit',\n color: 'inherit',\n textAlign: 'left',\n cursor: 'pointer',\n background: 'transparent',\n border: 0,\n borderRadius: 12,\n alignItems: 'center',\n gap: 12,\n padding: '14px 16px',\n display: 'flex',\n}\n\nconst headTextStyle: CSSProperties = {\n flexDirection: 'column',\n flex: 1,\n gap: 4,\n minWidth: 0,\n display: 'flex',\n}\n\nconst nameStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-primary, inherit)',\n fontSize: 15,\n fontWeight: 600,\n lineHeight: 1.4,\n}\n\nconst descStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary, rgba(128,128,128,0.7))',\n fontSize: 13,\n lineHeight: 1.5,\n}\n\nconst pendingStyle: CSSProperties = {\n whiteSpace: 'nowrap',\n background: 'var(--dsw-alias-bg-module-platform, rgba(128,128,128,0.12))',\n color: 'var(--dsw-alias-label-secondary, inherit)',\n borderRadius: 999,\n flex: 'none',\n padding: '1px 8px',\n fontSize: 11,\n fontWeight: 500,\n lineHeight: '17px',\n}\n\nconst chevronStyle = (open: boolean): CSSProperties => ({\n color: 'var(--dsw-alias-label-tertiary, inherit)',\n flex: 'none',\n transition: 'transform .16s',\n display: 'inline-flex',\n alignItems: 'center',\n transform: open ? 'rotate(180deg)' : 'none',\n})\n\nconst bodyStyle: CSSProperties = {\n borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.22))',\n margin: '0 16px',\n padding: '12px 0 4px',\n}\n\nconst formStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n}\n\nconst fieldStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n}\n\nconst labelStyle: CSSProperties = {\n display: 'block',\n fontSize: 13,\n fontWeight: 500,\n color: 'var(--dsw-alias-label-primary, inherit)',\n}\n\nconst inputStyle: CSSProperties = {\n width: '100%',\n padding: '6px 10px',\n fontSize: 13,\n borderRadius: 8,\n border: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.3))',\n background: 'var(--dsw-alias-bg-layer-3, transparent)',\n color: 'var(--dsw-alias-label-primary, inherit)',\n boxSizing: 'border-box',\n fontFamily: 'inherit',\n}\n\nconst hintStyle: CSSProperties = {\n fontSize: 12,\n color: 'var(--dsw-alias-label-tertiary, rgba(128,128,128,0.6))',\n margin: 0,\n lineHeight: 1.5,\n}\n\nconst footerStyle: CSSProperties = {\n borderTop: '1px solid var(--dsw-alias-border-l2, rgba(128,128,128,0.22))',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: 8,\n padding: '12px 0 4px',\n display: 'flex',\n}\n\nconst btnBase: CSSProperties = {\n appearance: 'none',\n font: 'inherit',\n cursor: 'pointer',\n border: '1px solid transparent',\n borderRadius: 8,\n padding: '5px 14px',\n fontSize: 13,\n fontWeight: 500,\n lineHeight: '20px',\n color: 'var(--dsw-alias-label-primary, inherit)',\n background: 'var(--dsw-alias-bg-module-platform, rgba(128,128,128,0.12))',\n transition: 'background .16s, opacity .16s',\n}\n\nconst noticeStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-tertiary, rgba(128,128,128,0.7))',\n margin: '0 0 8px',\n fontSize: 12,\n lineHeight: 1.5,\n}\n\nconst savedStyle: CSSProperties = {\n color: 'var(--dsw-alias-state-success-primary, #30d158)',\n margin: '0 0 12px',\n fontSize: 12,\n lineHeight: 1.5,\n}\n\nconst errorStyle: CSSProperties = {\n color: 'var(--dsw-alias-label-error, #ff453a)',\n margin: '0 0 12px',\n fontSize: 12,\n lineHeight: 1.5,\n minWidth: 0,\n}\n\nconst CHEVRON_SVG = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>'\n\n/**\n * Render the sidebar-brand-text settings card.\n * @param props - locale + controller/useSnapshot inject.\n * @returns a `<li>` card element.\n */\nexport function BrandTextCard({ t, controller, useSnapshot }: BrandTextCardProps) {\n const state = useSnapshot((s) => s)\n if (state.status === 'idle') void controller.load()\n\n const degraded = state.status === 'ready' && !state.available\n const open = state._open || degraded\n const applyState = state.applyState ?? { kind: 'idle' }\n const saving = applyState.kind === 'saving'\n const saved = applyState.kind === 'saved'\n const errorText = applyState.kind === 'error' ? applyState.message : undefined\n const busy = !state.writable || saving\n\n const header = (\n <button\n type=\"button\"\n style={headerStyle}\n aria-expanded={open}\n aria-label={t('card.title')}\n onClick={() => { if (!degraded) controller.toggle() }}\n >\n <span style={headTextStyle}>\n <span style={nameStyle}>{t('card.title')}</span>\n <span style={descStyle}>{t('card.intro')}</span>\n </span>\n {state.dirty ? <span style={pendingStyle}>{t('card.unsaved')}</span> : null}\n <span style={chevronStyle(open)} dangerouslySetInnerHTML={{ __html: CHEVRON_SVG }} />\n </button>\n )\n\n let body: React.ReactNode = null\n if (open) {\n if (!state.available) {\n body = (\n <div style={bodyStyle}>\n <p style={noticeStyle} role=\"status\">{t('card.unavailable')}</p>\n <div style={footerStyle}>\n <button\n type=\"button\"\n style={btnBase}\n onClick={() => { void controller.load() }}\n >\n {t('card.retry')}\n </button>\n </div>\n </div>\n )\n } else {\n body = (\n <div style={bodyStyle}>\n {saved ? <p style={savedStyle} role=\"status\">{t('card.saved')}</p> : null}\n {errorText !== undefined ? <p style={errorStyle} role=\"status\">{errorText}</p> : null}\n <div style={formStyle}>\n <div style={fieldStyle}>\n <label style={labelStyle} htmlFor=\"sbbt-name\">{t('field.name.label')}</label>\n <input\n id=\"sbbt-name\"\n type=\"text\"\n style={inputStyle}\n value={state.draft.name}\n placeholder={t('field.name.placeholder')}\n disabled={busy}\n onChange={(e) => controller.edit('name', e.target.value)}\n />\n <p style={hintStyle}>{t('field.name.hint')}</p>\n </div>\n <div style={fieldStyle}>\n <label style={labelStyle} htmlFor=\"sbbt-revision\">{t('field.revision.label')}</label>\n <input\n id=\"sbbt-revision\"\n type=\"text\"\n style={inputStyle}\n value={state.draft.revision}\n placeholder={t('field.revision.placeholder')}\n disabled={busy}\n onChange={(e) => controller.edit('revision', e.target.value)}\n />\n <p style={hintStyle}>{t('field.revision.hint')}</p>\n </div>\n </div>\n <div style={footerStyle}>\n <button\n type=\"button\"\n style={{ ...btnBase, opacity: (!state.dirty || saving) ? 0.5 : 1 }}\n disabled={!state.dirty || saving}\n onClick={() => controller.discard()}\n >\n {t('card.discard')}\n </button>\n <button\n type=\"button\"\n style={{\n ...btnBase,\n background: 'var(--dsw-alias-brand-primary, #0a84ff)',\n color: 'var(--dsw-alias-bg-layer-1, #fff)',\n opacity: (!state.dirty || saving) ? 0.5 : 1,\n }}\n disabled={!state.dirty || saving}\n onClick={() => { void controller.save() }}\n >\n {saving ? t('card.saving') : t('card.save')}\n </button>\n </div>\n </div>\n )\n }\n }\n\n return (\n <li style={cardStyle}>\n {header}\n {open ? body : null}\n </li>\n )\n}\n","/**\n * `BrandTextSettingsController` — client-side state store for the\n * sidebar-brand-text config.\n *\n * Loads the config from the host's `/sbbt/api/get` route, stages edits,\n * and saves via `/sbbt/api/set`. The `sidebar.brand.name` slot occupant\n * and the `settings.plugin.item` card both read from the same store via\n * `bindSnapshotSelector`, so a save is instantly reflected in the sidebar\n * without a DOM event or page reload.\n *\n * Mirrors the ego-browser `EgoBrowserSettingsController` pattern.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/controller\n */\nimport { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { DEFAULT_BRAND_TEXT_CONFIG, type BrandTextConfig } from '../types.ts'\n\n/** The controller's snapshot state. */\nexport interface BrandTextState {\n /** 'idle' | 'loading' | 'ready' */\n status: 'idle' | 'loading' | 'ready'\n /** True after a successful `/sbbt/api/get`; false when the route is unreachable. */\n available: boolean\n /** False when the settings service is absent (read-only). */\n writable: boolean\n /** Current draft values (edited by the card, read by the brand slot). */\n draft: BrandTextConfig\n /** True when the draft differs from the last-saved config. */\n dirty: boolean\n /** Apply lifecycle: 'idle' | 'saving' | 'saved' | 'error'. */\n applyState: { kind: 'idle' } | { kind: 'saving' } | { kind: 'saved' } | { kind: 'error', message: string }\n /** Card expand state (toggled by the card header button). */\n _open: boolean\n}\n\n/** Initial state before the first load. */\nfunction initialState(): BrandTextState {\n return {\n status: 'idle',\n available: false,\n writable: false,\n draft: { ...DEFAULT_BRAND_TEXT_CONFIG },\n dirty: false,\n applyState: { kind: 'idle' },\n _open: false,\n }\n}\n\n/**\n * Controller managing the brand-text config lifecycle.\n *\n * Constructed once in the client `apply()` and shared between the\n * `sidebar.brand.name` slot and the `settings.plugin.item` card.\n */\nexport class BrandTextSettingsController {\n readonly store: SnapshotStore<BrandTextState>\n loaded = false\n private generation = 0\n\n constructor() {\n this.store = createSnapshotStore<BrandTextState>(initialState())\n }\n\n /** Fetch the config from `/sbbt/api/get` and update the store. */\n async load(): Promise<void> {\n const gen = ++this.generation\n this.store.update((s) => { s.status = 'loading' })\n try {\n const res = await fetch('/sbbt/api/get', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: '{}',\n })\n if (!res.ok) {\n this.markUnavailable(gen)\n return\n }\n const parsed = await res.json().catch(() => null)\n if (gen !== this.generation) return\n if (!parsed || parsed.ok !== true || !parsed.value) {\n this.markUnavailable(gen)\n return\n }\n const config = parsed.value.config as BrandTextConfig | undefined\n this.loaded = true\n this.store.update((s) => {\n s.status = 'ready'\n s.available = true\n s.writable = true\n if (config) {\n s.draft = { name: config.name, revision: config.revision }\n }\n s.dirty = false\n s.applyState = { kind: 'idle' }\n })\n } catch {\n this.markUnavailable(gen)\n }\n }\n\n /** Stage an edit to a field (does not save). */\n edit(field: 'name' | 'revision', value: string): void {\n this.store.update((s) => {\n if (field === 'name') s.draft.name = value\n else s.draft.revision = value\n s.dirty = true\n s.applyState = { kind: 'idle' }\n })\n }\n\n /** Discard staged edits and reload from the host. */\n discard(): void {\n void this.load()\n }\n\n /** Save the staged draft via `/sbbt/api/set`. */\n async save(): Promise<void> {\n const gen = ++this.generation\n const snapshot = this.store.getSnapshot()\n if (!snapshot.dirty) return\n this.store.update((s) => { s.applyState = { kind: 'saving' } })\n try {\n const res = await fetch('/sbbt/api/set', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ patch: snapshot.draft }),\n })\n const parsed = await res.json().catch(() => null)\n if (gen !== this.generation) return\n if (!parsed || parsed.ok !== true || !parsed.value) {\n const message = parsed?.error?.message ?? 'Save failed'\n this.store.update((s) => { s.applyState = { kind: 'error', message } })\n return\n }\n const config = parsed.value.config as BrandTextConfig | undefined\n this.store.update((s) => {\n s.applyState = { kind: 'saved' }\n if (config) {\n s.draft = { name: config.name, revision: config.revision }\n }\n s.dirty = false\n })\n } catch (error) {\n if (gen !== this.generation) return\n const message = error instanceof Error ? error.message : String(error)\n this.store.update((s) => { s.applyState = { kind: 'error', message } })\n }\n }\n\n /** Toggle the card's expand state (mirrors ego-browser `controller.toggle()`). */\n toggle(): void {\n this.store.update((s) => { s._open = !s._open })\n }\n\n /** Mark the store as unavailable (route unreachable or settings service absent). */\n private markUnavailable(gen: number): void {\n if (gen !== this.generation) return\n this.store.update((s) => {\n s.status = 'ready'\n s.available = false\n s.writable = false\n })\n }\n}\n","/**\n * Inlined `bindSnapshotSelector` — rc.8 dropped this from\n * `@deepseek-ai/dsh-client-ui-renderer`'s package root, so business plugins\n * carry their own copy. Uses React 18's built-in `useSyncExternalStore`\n * with per-snapshot selector memoization via `useRef` (same approach as\n * the ego-browser plugin).\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/bindSnapshotSelector\n */\nimport { useRef, useSyncExternalStore } from 'react'\nimport type { HostObservable, SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots'\n\n/**\n * Bind a React selector hook to a {@link HostObservable} snapshot source.\n * @param source - the observable snapshot store.\n * @returns a `useSelector(sel, eq?)` hook.\n */\nexport function bindSnapshotSelector<T>(source: HostObservable<T>): SnapshotSelectorHook<T> {\n const subscribe = (fn: () => void): (() => void) => source.subscribe(fn)\n const getSnapshot = (): T => source.getSnapshot()\n return function useSelector<S>(sel: (s: T) => S): S {\n const snapshot = useSyncExternalStore(subscribe, getSnapshot)\n const prevSnapshotRef = useRef<T | undefined>(undefined)\n const prevSelectedRef = useRef<S | undefined>(undefined)\n if (prevSnapshotRef.current !== snapshot) {\n prevSnapshotRef.current = snapshot\n prevSelectedRef.current = sel(snapshot)\n }\n return prevSelectedRef.current as S\n }\n}\n","/**\n * Overrides `document.title` so the configured brand name replaces the\n * build-time `DSH_CLIENT_TITLE` literal that `DocumentTitle.tsx` writes.\n *\n * DSH's built-in `DocumentTitle` component (ui-renderer) subscribes to\n * `sessions.list` and writes `<session title> — <productTitle>` where\n * `productTitle` is the build-time `process.env.DSH_CLIENT_TITLE` literal\n * (fallback `'DSH Local Build'`). That literal is baked into the bundle at\n * build time, so no slot or runtime config can touch it — see\n * `ui-brand-official/README.md` (\"The browser title is independent\").\n *\n * This writer subscribes to the **same** `sessions.list` feed and to the\n * shared `BrandTextSettingsController` store. After `DocumentTitle`'s\n * `useEffect` writes the title, this writer's `queueMicrotask` callback\n * overwrites it with `<session title> — <configured brand>`. A\n * `MutationObserver` on `<title>` is the backstop for React 18 concurrent\n * re-renders that may run after the microtask.\n *\n * On dispose, all subscriptions and the observer are torn down, and\n * `DocumentTitle`'s own `useEffect` cleanup restores the build-time title.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/titleWriter\n */\nimport type { BrandTextConfig } from '../types.ts'\nimport { DEFAULT_BRAND_TEXT_CONFIG } from '../types.ts'\nimport type { BrandTextState } from './controller.ts'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\n\n/** Minimal face of `sessions.list` we depend on (ISessions.list slice). */\ninterface SessionListSnapshot {\n current: string | undefined\n byId: Record<string, { title?: string } | undefined>\n}\n\n/** Minimal face of the `sessions` service we depend on. */\ninterface SessionsLike {\n readonly list: {\n getSnapshot(): SessionListSnapshot\n subscribe(fn: () => void): () => void\n }\n}\n\n/** Disposer returned by {@link startTitleWriter}. */\nexport type TitleWriterDisposer = () => void\n\n/**\n * Start overriding `document.title` with the configured brand name.\n *\n * @param sessions - the cordis `sessions` service (read-only face).\n * @param store - the shared `BrandTextSettingsController` store; the title\n * updates when the config changes (card save) as well as when the current\n * session changes.\n * @returns a disposer that tears down all subscriptions and the observer.\n */\nexport function startTitleWriter(\n sessions: SessionsLike | undefined,\n store: SnapshotStore<BrandTextState>,\n): TitleWriterDisposer {\n if (sessions === undefined) return () => {}\n if (typeof document === 'undefined') return () => {}\n\n /** Compute the title we want, from the current session + brand config. */\n const computeTitle = (): string => {\n const state = store.getSnapshot()\n const cfg: BrandTextConfig = state.available ? state.draft : DEFAULT_BRAND_TEXT_CONFIG\n const list = sessions.list.getSnapshot()\n const id = list.current\n const sessionTitle = id === undefined ? undefined : list.byId[id]?.title\n return sessionTitle === undefined || sessionTitle === ''\n ? cfg.name\n : `${sessionTitle} — ${cfg.name}`\n }\n\n /** Write the computed title if it differs (avoids spurious observer fires). */\n const applyTitle = (): void => {\n const expected = computeTitle()\n if (document.title !== expected) document.title = expected\n }\n\n /** Deferred writer: runs after React's useEffect via microtask. */\n const deferredApply = (): void => { queueMicrotask(applyTitle) }\n\n const stopSessionSub = sessions.list.subscribe(deferredApply)\n const stopStoreSub = store.subscribe(deferredApply)\n\n let observer: MutationObserver | null = null\n const titleEl = document.querySelector('title')\n if (titleEl !== null) {\n observer = new MutationObserver(applyTitle)\n observer.observe(titleEl, { childList: true, subtree: true, characterData: true })\n }\n\n queueMicrotask(applyTitle)\n\n return () => {\n stopSessionSub()\n stopStoreSub()\n observer?.disconnect()\n observer = null\n }\n}\n","/**\n * Locale dictionaries for the `dsh-plugin-sidebar-brand-text` namespace.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client/locales\n */\n\n/** The locale keys the settings card reads. */\nexport type BrandTextKey =\n | 'card.title'\n | 'card.intro'\n | 'card.unsaved'\n | 'card.saved'\n | 'card.saving'\n | 'card.discard'\n | 'card.save'\n | 'card.unavailable'\n | 'card.retry'\n | 'field.name.label'\n | 'field.name.placeholder'\n | 'field.name.hint'\n | 'field.revision.label'\n | 'field.revision.placeholder'\n | 'field.revision.hint'\n\n/** The locale namespace name; matches the `locale: NS` passed at slot register. */\nexport const NS = 'dsh-plugin-sidebar-brand-text'\n\n/** English dictionary. */\nexport const en: Record<BrandTextKey, string> = {\n 'card.title': 'Sidebar Brand Text',\n 'card.intro': 'Replace the sidebar brand name and revision badge with custom text.',\n 'card.unsaved': 'Unsaved',\n 'card.saved': 'Saved',\n 'card.saving': 'Saving…',\n 'card.discard': 'Discard',\n 'card.save': 'Save',\n 'card.unavailable': 'The sidebar-brand-text configuration channel is unavailable. Please retry later.',\n 'card.retry': 'Retry',\n 'field.name.label': 'Brand name',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': 'Text shown in the sidebar next to the logo. Replaces the default \"DSH Local Build\".',\n 'field.revision.label': 'Revision badge',\n 'field.revision.placeholder': 'e.g. v1.0.0 or abc1234',\n 'field.revision.hint': 'Small badge text beside the brand name. Leave empty to hide the badge.',\n}\n\n/** Chinese dictionary. */\nexport const zh: Record<BrandTextKey, string> = {\n 'card.title': '侧边栏品牌文案',\n 'card.intro': '替换侧边栏左上角的品牌名与构建徽标文案。',\n 'card.unsaved': '未保存',\n 'card.saved': '已保存',\n 'card.saving': '保存中…',\n 'card.discard': '放弃',\n 'card.save': '保存',\n 'card.unavailable': '侧边栏品牌文案配置通道不可用,请稍后重试。',\n 'card.retry': '重试',\n 'field.name.label': '品牌名称',\n 'field.name.placeholder': 'DSH Local Build',\n 'field.name.hint': '侧边栏 logo 右侧显示的文案。替换默认的「DSH Local Build」。',\n 'field.revision.label': '版本徽标',\n 'field.revision.placeholder': '如 v1.0.0 或 abc1234',\n 'field.revision.hint': '品牌名右侧的小徽标文案。留空则不显示徽标。',\n}\n","/**\n * One scoped stylesheet injected for the lifetime of the client activation.\n *\n * The shell's `sidebar.brand.name` fallback renders two CSS-Module-hashed\n * spans (`.fallbackBrandName` + `.buildRevision`); those class names are\n * not stable across builds and not addressable from outside the sidebar\n * package. This plugin ships its own class names with the same visual\n * intent, all colors and typography drawn from the shared `--dsw-*`\n * tokens (never literals) so the badge tracks the active theme.\n *\n * The parent `.brandName` span (inline-flex, gap: 6px, font-size: 18px,\n * font-weight: 600) is owned by the sidebar shell and wraps whatever the\n * slot occupant returns, so this stylesheet only needs to style the two\n * child spans.\n */\nexport const CSS = `\n.sbbt-brand-name {\n font-size: 17px;\n letter-spacing: 0px;\n white-space: nowrap;\n}\n\n.sbbt-build-revision {\n display: inline-flex;\n align-items: center;\n height: 16px;\n padding: 0 4px;\n border-radius: 3px;\n color: var(--dsw-alias-label-primary-inverted);\n background: var(--dsw-alias-label-primary);\n font-family: var(--ds-font-family-code);\n font-size: 8px;\n font-weight: 500;\n line-height: 16px;\n}\n`\n\n/**\n * Install the stylesheet and return its disposer.\n * @returns a cleanup function that removes the injected `<style>` tag.\n */\nexport function installStyles(): () => void {\n if (typeof document === 'undefined') return () => {}\n const style = document.createElement('style')\n style.setAttribute('data-sidebar-brand-text-style', '')\n style.textContent = CSS\n document.head.appendChild(style)\n return () => { style.remove() }\n}\n","/**\n * sidebar-brand-text — browser half.\n *\n * Two registrations:\n * - `settings.plugin.item` keyed slot (key `sidebar-brand-text`) — a card\n * in the Plugin Config page with two text inputs (name + revision).\n * Reads/writes through the `/sbbt/api` HTTP route via the shared\n * `BrandTextSettingsController`.\n * - `sidebar.brand.name` single slot — renders the configured brand name\n * text and optional revision badge. Reads from the same controller\n * store via `useSnapshot`, so a save in the card is instantly\n * reflected in the sidebar.\n *\n * The mark slot (`sidebar.brand.mark`) is deliberately NOT registered:\n * the fish logo stays in place unless another plugin (e.g.\n * `ui-brand-official`) replaces it.\n *\n * @module @huanlin/dsh-plugin-sidebar-brand-text/client\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-api-session-controller/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { dicts } from './dictionaries.ts'\nimport { BrandText, type BrandTextInjected } from './BrandText.tsx'\nimport { BrandTextCard, type BrandTextCardInjected } from './BrandTextCard.tsx'\nimport { BrandTextSettingsController } from './controller.ts'\nimport { bindSnapshotSelector } from './bindSnapshotSelector.ts'\nimport { startTitleWriter } from './titleWriter.ts'\nimport { en, NS, zh, type BrandTextKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\n\n/** Structural view of the `ctx.betterLocale` service (published by dsh-plugin-better-locale). */\ninterface BetterLocaleStoreLike {\n register(ns: string, dicts: Record<string, Record<string, string>>): () => void\n}\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The settings card labels. */\n 'dsh-plugin-sidebar-brand-text': BrandTextKey\n }\n}\n\n/** Required services: slots + locale + sessions (sessions drives the title writer). */\nexport const inject = ['slots', 'locale', 'sessions']\n\n/**\n * Client plugin body: register the brand-name slot occupant, the settings\n * card, the locale dictionary, and the stylesheet.\n *\n * A single `BrandTextSettingsController` is shared between the card and\n * the brand text so a save is instantly reflected in the sidebar.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'sidebar-brand-text: dictionaries')\n ctx.effect(() => {\n let dispose: (() => void) | undefined\n const sync = (): void => {\n dispose?.()\n dispose = undefined\n const store = ctx.get('betterLocale') as BetterLocaleStoreLike | undefined\n if (store !== undefined) {\n dispose = store.register(NS, dicts)\n }\n }\n sync()\n const unsubscribe = ctx.locale.subscribe(sync)\n return () => {\n unsubscribe()\n dispose?.()\n }\n }, 'dsh-plugin-sidebar-brand-text: better-locale override dicts')\n ctx.effect(installStyles, 'sidebar-brand-text: styles')\n\n const controller = new BrandTextSettingsController()\n const useSnapshot = bindSnapshotSelector(controller.store)\n\n void controller.load()\n\n ctx.effect(() => startTitleWriter(ctx.sessions, controller.store), 'sidebar-brand-text: document.title override')\n\n const brandInjected = (): BrandTextInjected => ({ useSnapshot })\n ctx.slots.inject('sidebar.brand.name', () =>\n ctx.slots.register(\n {\n name: 'sidebar.brand.name',\n inject: brandInjected,\n },\n BrandText,\n ),\n )\n\n const cardInjected = (): BrandTextCardInjected => ({ controller, useSnapshot })\n ctx.slots.inject('settings.plugin.item', function* () {\n yield ctx.slots.register(\n {\n name: 'settings.plugin.item',\n key: 'sidebar-brand-text',\n locale: NS,\n inject: cardInjected,\n },\n BrandTextCard,\n )\n })\n}\n"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
|
-
import { settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
3
2
|
|
|
4
3
|
//#region src/config.ts
|
|
5
4
|
/** Schemastery schema for the composition entry and the settings namespace. */
|
|
@@ -31,7 +30,7 @@ const DEFAULT = {
|
|
|
31
30
|
//#endregion
|
|
32
31
|
//#region src/settings.ts
|
|
33
32
|
/** Settings namespace under which brand-text config persists. */
|
|
34
|
-
const SETTINGS_NAMESPACE =
|
|
33
|
+
const SETTINGS_NAMESPACE = "sidebar-brand-text";
|
|
35
34
|
/**
|
|
36
35
|
* Mirror of the dsh-settings internal `isUnloading` guard. The cordis const
|
|
37
36
|
* enum for fiber state is erased at compile time, so the literal states are
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @module @huanlin/dsh-plugin-sidebar-brand-text/client/controller
|
|
14
14
|
*/
|
|
15
|
-
import { type SnapshotStore } from '@deepseek-ai/dsh-client-
|
|
15
|
+
import { type SnapshotStore } from '@deepseek-ai/dsh-client-store';
|
|
16
16
|
import { type BrandTextConfig } from '../types.ts';
|
|
17
17
|
/** The controller's snapshot state. */
|
|
18
18
|
export interface BrandTextState {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @module @huanlin/dsh-plugin-sidebar-brand-text/client
|
|
19
19
|
*/
|
|
20
|
-
import type { ClientContext } from '@deepseek-ai/
|
|
20
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
21
21
|
import { type BrandTextKey } from './locales.ts';
|
|
22
22
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
23
23
|
interface LocaleNamespaceMap {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BrandTextState } from './controller.ts';
|
|
2
|
-
import type { SnapshotStore } from '@deepseek-ai/dsh-client-
|
|
2
|
+
import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
|
|
3
3
|
/** Minimal face of `sessions.list` we depend on (ISessions.list slice). */
|
|
4
4
|
interface SessionListSnapshot {
|
|
5
5
|
current: string | undefined;
|
package/lib/types/settings.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import type { Context } from '@deepseek-ai/cordis';
|
|
14
14
|
import type { BrandTextConfig } from './types.ts';
|
|
15
15
|
/** Settings namespace under which brand-text config persists. */
|
|
16
|
-
export declare const SETTINGS_NAMESPACE:
|
|
16
|
+
export declare const SETTINGS_NAMESPACE: "sidebar-brand-text";
|
|
17
17
|
/** Bridge returned by {@link installBrandTextSettings}. */
|
|
18
18
|
export interface BrandTextSettingsBridge {
|
|
19
19
|
/** Read the current resolved config (entry source or settings layer). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huanlin/dsh-plugin-sidebar-brand-text",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -17,10 +17,6 @@
|
|
|
17
17
|
"types": "./lib/types/index.d.ts",
|
|
18
18
|
"import": "./lib/index.js"
|
|
19
19
|
},
|
|
20
|
-
"./invariant": {
|
|
21
|
-
"types": "./lib/types/invariant.d.ts",
|
|
22
|
-
"import": "./lib/invariant.js"
|
|
23
|
-
},
|
|
24
20
|
"./client": {
|
|
25
21
|
"types": "./lib/types/client/index.d.ts",
|
|
26
22
|
"default": "./lib/client.js"
|
|
@@ -38,24 +34,27 @@
|
|
|
38
34
|
},
|
|
39
35
|
"client": {
|
|
40
36
|
"inject": [
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
37
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
42
38
|
"@deepseek-ai/dsh-client-locale",
|
|
43
|
-
"@deepseek-ai/dsh-client-
|
|
39
|
+
"@deepseek-ai/dsh-client-store",
|
|
40
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
41
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins",
|
|
44
42
|
"@deepseek-ai/dsh-client-ui-sidebar",
|
|
45
|
-
"@deepseek-ai/dsh-client-ui-
|
|
43
|
+
"@deepseek-ai/dsh-client-ui-slots"
|
|
46
44
|
],
|
|
47
45
|
"platform": "web"
|
|
48
46
|
}
|
|
49
47
|
},
|
|
50
48
|
"peerDependencies": {
|
|
51
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-client-
|
|
54
|
-
"@deepseek-ai/dsh-client-
|
|
55
|
-
"@deepseek-ai/dsh-client-ui-
|
|
56
|
-
"@deepseek-ai/dsh-client-ui-
|
|
57
|
-
"@deepseek-ai/dsh-
|
|
58
|
-
"@deepseek-ai/dsh-
|
|
49
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
50
|
+
"@deepseek-ai/dsh-api-session-controller": "^0.1.2-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
|
|
52
|
+
"@deepseek-ai/dsh-client-store": "^0.1.2-rc.1",
|
|
53
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-rc.1",
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.2-rc.1",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.1.2-rc.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
|
|
57
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-rc.1",
|
|
59
58
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
60
59
|
"react": "^18.2.0"
|
|
61
60
|
},
|
|
@@ -63,10 +62,16 @@
|
|
|
63
62
|
"@deepseek-ai/cordis": {
|
|
64
63
|
"optional": true
|
|
65
64
|
},
|
|
65
|
+
"@deepseek-ai/dsh-api-session-controller": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
66
68
|
"@deepseek-ai/dsh-client-locale": {
|
|
67
69
|
"optional": true
|
|
68
70
|
},
|
|
69
|
-
"@deepseek-ai/dsh-client-
|
|
71
|
+
"@deepseek-ai/dsh-client-store": {
|
|
72
|
+
"optional": true
|
|
73
|
+
},
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-renderer": {
|
|
70
75
|
"optional": true
|
|
71
76
|
},
|
|
72
77
|
"@deepseek-ai/dsh-client-ui-settings-plugins": {
|
|
@@ -78,9 +83,6 @@
|
|
|
78
83
|
"@deepseek-ai/dsh-client-ui-slots": {
|
|
79
84
|
"optional": true
|
|
80
85
|
},
|
|
81
|
-
"@deepseek-ai/dsh-invariants": {
|
|
82
|
-
"optional": true
|
|
83
|
-
},
|
|
84
86
|
"@deepseek-ai/dsh-settings": {
|
|
85
87
|
"optional": true
|
|
86
88
|
},
|
|
@@ -92,14 +94,7 @@
|
|
|
92
94
|
}
|
|
93
95
|
},
|
|
94
96
|
"devDependencies": {
|
|
95
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
96
|
-
"@deepseek-ai/dsh-client-locale": "0.1.0-rc.8",
|
|
97
|
-
"@deepseek-ai/dsh-client-runtime": "0.1.0-rc.8",
|
|
98
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.0-rc.8",
|
|
99
|
-
"@deepseek-ai/dsh-client-ui-sidebar": "0.1.0-rc.8",
|
|
100
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.8",
|
|
101
|
-
"@deepseek-ai/dsh-invariants": "0.1.0-rc.8",
|
|
102
|
-
"@deepseek-ai/dsh-settings": "0.1.0-rc.8",
|
|
97
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
103
98
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
104
99
|
"@types/node": "^22.20.1",
|
|
105
100
|
"@types/react": "~18.3.31",
|
package/lib/invariant.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
//#region src/invariant.ts
|
|
2
|
-
const PACKAGE_NAME = "@huanlin/dsh-plugin-sidebar-brand-text";
|
|
3
|
-
const name = "sidebar-brand-text-invariant";
|
|
4
|
-
const inject = ["invariants"];
|
|
5
|
-
/**
|
|
6
|
-
* No runtime invariant: the single `sidebar.brand.name` slot registration
|
|
7
|
-
* is a registry-owned contribution whose disposal is proven by the
|
|
8
|
-
* declaration-aware `slots.inject()` rollback. The plugin retains no
|
|
9
|
-
* mutable state beyond the config snapshot closed over by the inject
|
|
10
|
-
* factory.
|
|
11
|
-
*/
|
|
12
|
-
const install = () => {};
|
|
13
|
-
/**
|
|
14
|
-
* Register this package's invariant companion.
|
|
15
|
-
* @param ctx - Cordis context carrying the invariant service.
|
|
16
|
-
* @returns the installed registration's disposer after setup succeeds.
|
|
17
|
-
*/
|
|
18
|
-
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
19
|
-
|
|
20
|
-
//#endregion
|
|
21
|
-
export { apply, inject, name };
|
package/lib/types/invariant.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/** Package invariant companion for dsh-plugin-sidebar-brand-text. */
|
|
2
|
-
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
-
export declare const name = "sidebar-brand-text-invariant";
|
|
4
|
-
export declare const inject: string[];
|
|
5
|
-
/**
|
|
6
|
-
* Register this package's invariant companion.
|
|
7
|
-
* @param ctx - Cordis context carrying the invariant service.
|
|
8
|
-
* @returns the installed registration's disposer after setup succeeds.
|
|
9
|
-
*/
|
|
10
|
-
export declare const apply: (ctx: Context) => Promise<() => void>;
|