@mhfire/dsh-im-bridge 0.1.3 → 0.2.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","names":["useState","css","IconChevronDownOutline14","css","createSnapshotStore","NS"],"sources":["../src/client/PluginCard.tsx","../src/client/fields.tsx","../src/client/WecomCard.tsx","../src/client/card-form.ts","../src/client/card-controller.ts","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["/** Expandable plugin card chrome matching the Host Plugins section. */\n\nimport { useState, type ReactElement, type ReactNode } from 'react'\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ImBridgeLocaleKey } from './locales.ts'\nimport type { CardShell } from './card-form.ts'\nimport css from './PluginCard.module.css'\n\n/** Card chrome shared by this plugin's settings card. */\nexport interface PluginCardProps {\n /** Locale reader for this card's copy. */\n t: (key: ImBridgeLocaleKey) => string\n /** Locale key of the plugin's name. */\n titleKey: ImBridgeLocaleKey\n /** Locale key of the line describing what these settings govern. */\n descriptionKey: ImBridgeLocaleKey\n /** The card's form state. */\n state: CardShell\n /** Write every staged edit. */\n onSave: () => void\n /** Drop every staged edit. */\n onDiscard: () => void\n /** The plugin's controls. */\n children: ReactNode\n}\n\n/**\n * Render one plugin card.\n * @param props - locale copy, form state, and controls.\n * @returns the card, or nothing when the namespace is unavailable.\n */\nexport function PluginCard(props: PluginCardProps): ReactElement | null {\n const [open, setOpen] = useState(false)\n const { state } = props\n if (!state.available) return null\n const title = props.t(props.titleKey)\n const blocked = !state.dirty || state.invalid || state.saving\n return (\n <li className={open ? `${css.card} ${css.cardOpen}` : css.card}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${props.t(open ? 'collapse' : 'expand')}: ${title}`}\n onClick={() => { setOpen(current => !current) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}</span>\n <span className={css.description}>{props.t(props.descriptionKey)}</span>\n </span>\n {state.dirty ? <span className={css.pending}>{props.t('unsaved')}</span> : null}\n <IconChevronDownOutline14 className={open ? `${css.chevron} ${css.chevronOpen}` : css.chevron} />\n </button>\n {open\n ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{props.t('readOnly')}</p> : null}\n {props.children}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role=\"status\">{props.t('saveFailed')}</p> : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.onDiscard}\n >\n {props.t('discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.onSave}\n >\n {props.t(state.saving ? 'saving' : 'save')}\n </button>\n </div>\n </div>\n )\n : null}\n </li>\n )\n}\n","/** Staged value and write-only secret controls. */\n\nimport type { ReactElement } from 'react'\nimport css from './fields.module.css'\n\n/** Shared props for a labelled field control. */\nexport interface FieldProps {\n /** Stable id associating the label with its control. */\n id: string\n /** Visible label. */\n label: string\n /** One-line explanation under the control. */\n hint: string\n /** Draft text the control renders. */\n text: string\n /** Whether saving would leave a user-layer entry. */\n overridden: boolean\n /** Whether the draft is not a value this field accepts. */\n invalid: boolean\n /** Copy for the overridden badge. */\n overriddenLabel: string\n /** Copy for the reset control. */\n resetLabel: string\n /** Copy shown in place of the hint while the draft is invalid. */\n invalidLabel: string\n /** Disables every control. */\n disabled: boolean\n /** Stage draft text. */\n onEdit: (text: string) => void\n /** Stage a clear so the field re-inherits the composition layer. */\n onReset: () => void\n}\n\n/**\n * A staged value field.\n * @param props - the field's copy, staged text, and edit actions.\n * @returns the labelled control.\n */\nexport function ValueField(props: FieldProps & {\n /** Hints a numeric keypad without narrowing accepted drafts. */\n numeric?: boolean\n}): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden\n ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button\n type=\"button\"\n className={css.reset}\n disabled={props.disabled}\n onClick={props.onReset}\n >\n {props.resetLabel}\n </button>\n </span>\n )\n : null}\n </div>\n <input\n id={props.id}\n className={props.invalid ? css.inputInvalid : css.input}\n type=\"text\"\n {...props.numeric === true ? { inputMode: 'numeric' as const } : {}}\n {...props.invalid ? { 'aria-invalid': true } : {}}\n value={props.text}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <p className={props.invalid ? css.invalid : css.hint}>\n {props.invalid ? props.invalidLabel : props.hint}\n </p>\n </div>\n )\n}\n\n/**\n * Write-only credential control. The literal never rides a response, so the\n * control starts blank and reports only whether one is configured.\n * @param props - the field's copy, staged text, and configured state.\n * @returns the labelled control.\n */\nexport function SecretField(props: Pick<FieldProps, 'id' | 'label' | 'hint' | 'text' | 'disabled' | 'onEdit'> & {\n /** Whether the Host reports a configured value for this secret slot. */\n configured: boolean\n /** Copy describing the configured state. */\n stateLabel: string\n}): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n <span className={css.badges}>\n <span className={props.configured ? css.badge : css.badgeMuted}>{props.stateLabel}</span>\n </span>\n </div>\n <input\n id={props.id}\n className={css.input}\n type=\"password\"\n autoComplete=\"off\"\n value={props.text}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n","/** WeCom settings card: owned chrome, staged fields, save/discard. */\n\nimport type { ReactElement } from 'react'\nimport type { ImBridgeLocaleKey } from './locales.ts'\nimport type { WecomCardFace, WecomCardState } from './card-controller.ts'\nimport { PluginCard } from './PluginCard.tsx'\nimport { SecretField, ValueField } from './fields.tsx'\n\n/** Props the slot renderer binds for this card. */\nexport interface WecomCardProps {\n /** Translate a dictionary key of the `im-bridge` namespace. */\n t: (key: ImBridgeLocaleKey) => string\n /** Card snapshot bound from inject.hooks.wecomCard. */\n useWecomCard: <S>(select: (state: WecomCardState) => S) => S\n /** Stage draft text for one field. */\n edit: WecomCardFace['edit']\n /** Stage a clear back to the composition layer. */\n resetField: WecomCardFace['resetField']\n /** Write every staged edit. */\n save: WecomCardFace['save']\n /** Drop every staged edit. */\n discard: WecomCardFace['discard']\n}\n\n/**\n * Render the WeCom settings card.\n * @param props - locale copy, snapshot hook, and form actions.\n * @returns the card, or nothing when the namespace is unavailable.\n */\nexport function WecomCard(props: WecomCardProps): ReactElement | null {\n const { t } = props\n const state = props.useWecomCard(snapshot => snapshot)\n const disabled = !state.writable\n const field = {\n overriddenLabel: t('overridden'),\n resetLabel: t('reset'),\n invalidLabel: t('invalidNumber'),\n disabled,\n }\n return (\n <PluginCard\n t={t}\n titleKey=\"title\"\n descriptionKey=\"description\"\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <SecretField\n id=\"im-bridge-botId\"\n label={t('botId')}\n hint={t('secretHint')}\n disabled={disabled}\n text={state.botId.text}\n configured={state.botIdConfigured}\n stateLabel={state.botIdConfigured ? t('secretConfigured') : t('secretUnset')}\n onEdit={text => { props.edit('botId', text) }}\n />\n <SecretField\n id=\"im-bridge-secret\"\n label={t('secret')}\n hint={t('secretHint')}\n disabled={disabled}\n text={state.secret.text}\n configured={state.secretConfigured}\n stateLabel={state.secretConfigured ? t('secretConfigured') : t('secretUnset')}\n onEdit={text => { props.edit('secret', text) }}\n />\n <ValueField\n id=\"im-bridge-allowFrom\"\n label={t('allowFrom')}\n hint={t('allowFromHint')}\n {...field}\n {...state.allowFrom}\n onEdit={text => { props.edit('allowFrom', text) }}\n onReset={() => { props.resetField('allowFrom') }}\n />\n <ValueField\n id=\"im-bridge-agentTimeoutSec\"\n label={t('agentTimeoutSec')}\n hint={t('agentTimeoutSecHint')}\n numeric\n {...field}\n {...state.agentTimeoutSec}\n onEdit={text => { props.edit('agentTimeoutSec', text) }}\n onReset={() => { props.resetField('agentTimeoutSec') }}\n />\n <ValueField\n id=\"im-bridge-startHint\"\n label={t('startHint')}\n hint={t('startHintHint')}\n {...field}\n {...state.startHint}\n onEdit={text => { props.edit('startHint', text) }}\n onReset={() => { props.resetField('startHint') }}\n />\n <ValueField\n id=\"im-bridge-deniedMessage\"\n label={t('deniedMessage')}\n hint={t('deniedMessageHint')}\n {...field}\n {...state.deniedMessage}\n onEdit={text => { props.edit('deniedMessage', text) }}\n onReset={() => { props.resetField('deniedMessage') }}\n />\n <ValueField\n id=\"im-bridge-welcomeMessage\"\n label={t('welcomeMessage')}\n hint={t('welcomeMessageHint')}\n {...field}\n {...state.welcomeMessage}\n onEdit={text => { props.edit('welcomeMessage', text) }}\n onReset={() => { props.resetField('welcomeMessage') }}\n />\n <ValueField\n id=\"im-bridge-provider\"\n label={t('provider')}\n hint={t('providerHint')}\n {...field}\n {...state.provider}\n onEdit={text => { props.edit('provider', text) }}\n onReset={() => { props.resetField('provider') }}\n />\n <ValueField\n id=\"im-bridge-model\"\n label={t('model')}\n hint={t('modelHint')}\n {...field}\n {...state.model}\n onEdit={text => { props.edit('model', text) }}\n onReset={() => { props.resetField('model') }}\n />\n </PluginCard>\n )\n}\n","/**\n * Staged settings form owned by this plugin.\n * Mirrors the Host Plugins section model without importing its chrome.\n */\n\nimport {\n createSnapshotStore,\n type SettingsScope,\n type SettingsScopeSnapshot,\n type SnapshotStore,\n} from '@deepseek-ai/dsh-client-runtime/client'\n\n/** Write one staged field performs on save. */\nexport type FieldWrite =\n | { kind: 'set'; value: unknown }\n | { kind: 'clear' }\n\n/** Convert one section field between stored value and draft text. */\nexport interface CardFieldSpec {\n /** Field name inside the namespace section. */\n field: string\n /** Render a stored value as draft text. */\n format: (value: unknown) => string\n /** The write this draft stages, or undefined when the text is invalid. */\n parse: (text: string) => FieldWrite | undefined\n}\n\n/**\n * A control whose literal never rides a response. The draft starts blank;\n * a blank draft writes nothing so a save cannot clear a stored secret.\n */\nexport interface CardSecretSpec {\n /** Field name addressing this control inside the card's form. */\n field: string\n /** Write the staged text; resolves to whether the Host accepted it. */\n write: (text: string) => Promise<boolean>\n}\n\n/** One field as a control renders it. */\nexport interface CardFieldState {\n /** Draft text the control renders. */\n text: string\n /** Whether saving would leave a user-layer entry. */\n overridden: boolean\n /** Whether the draft is not a value this field accepts. */\n invalid: boolean\n}\n\n/** Card-level form state. */\nexport interface CardShell {\n /** False while the namespace is not served; the card renders nothing. */\n available: boolean\n /** Whether the Host document accepts writes. */\n writable: boolean\n /** Whether the form holds edits a save would write. */\n dirty: boolean\n /** Whether any staged draft is invalid. */\n invalid: boolean\n /** Whether a save is crossing the wire. */\n saving: boolean\n /** Whether the last save did not land. */\n failed: boolean\n}\n\n/** Write actions a card's slot entry injects. */\nexport interface CardActions {\n /** Stage draft text for one field. */\n edit: (field: string, text: string) => void\n /** Stage a clear so the field re-inherits the composition layer. */\n resetField: (field: string) => void\n /** Write every staged edit, then re-seed from what the Host accepted. */\n save: () => void\n /** Drop every staged edit. */\n discard: () => void\n}\n\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\ninterface PlannedWrite {\n field: string\n run: (() => Promise<boolean>) | undefined\n}\n\n/** Whole-number field. Empty draft clears. */\nexport function numberField(field: string): CardFieldSpec {\n return {\n field,\n format: value => typeof value === 'number' ? String(value) : '',\n parse: (text) => {\n const trimmed = text.trim()\n if (trimmed === '') return { kind: 'clear' }\n const parsed = Number(trimmed)\n return Number.isFinite(parsed) ? { kind: 'set', value: parsed } : undefined\n },\n }\n}\n\n/** Free-text field. Empty draft clears. */\nexport function textField(field: string): CardFieldSpec {\n return {\n field,\n format: value => typeof value === 'string' ? value : '',\n parse: (text) => {\n const trimmed = text.trim()\n return trimmed === '' ? { kind: 'clear' } : { kind: 'set', value: trimmed }\n },\n }\n}\n\n/** Comma-separated string list. Empty draft stores []. */\nexport function csvField(field: string): CardFieldSpec {\n return {\n field,\n format: value => Array.isArray(value) ? value.join(',') : '',\n parse: (text) => {\n const items = text.split(',').map(item => item.trim()).filter(Boolean)\n return { kind: 'set', value: items }\n },\n }\n}\n\n/** Stages edits over one settings namespace and writes them on save. */\nexport class CardForm<T> {\n private readonly specs: Map<string, CardFieldSpec>\n private readonly secretSpecs: Map<string, CardSecretSpec>\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n /**\n * @param scope - bound settings scope for this card's namespace.\n * @param specs - section fields this card edits.\n * @param secrets - write-only controls; a blank draft is a no-op.\n */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: CardFieldSpec[],\n secrets: CardSecretSpec[] = [],\n ) {\n this.specs = new Map(specs.map(spec => [spec.field, spec]))\n this.secretSpecs = new Map(secrets.map(spec => [spec.field, spec]))\n scope.subscribe(() => { this.publish() })\n }\n\n /** Publish a projection rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S): SnapshotStore<S> {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Card-level state: what the Host serves and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some(item => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** One control's staged text, override badge, and validity. */\n field(field: string): CardFieldState {\n const staged = this.staged.get(field)\n if (this.secretSpecs.has(field)) {\n return { text: staged?.text ?? '', overridden: false, invalid: false }\n }\n const spec = this.spec(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return {\n text: staged.text,\n overridden: write?.kind === 'set',\n invalid: write === undefined,\n }\n }\n\n /** Edit, reset, save, and discard actions bound to this form. */\n actions(): CardActions {\n return {\n edit: (field, text) => { this.stage(field, { text, clear: false }) },\n resetField: (field) => {\n this.stage(field, { text: this.spec(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.publish()\n },\n }\n }\n\n /** Write every staged edit, then re-seed from what the Host accepted. */\n async save(): Promise<void> {\n const plan = this.plan()\n const writes = plan.flatMap(item => item.run === undefined ? [] : [item.run])\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const write of writes) {\n landed = await write() && landed\n }\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n private plan(): PlannedWrite[] {\n const plan: PlannedWrite[] = []\n for (const [field, staged] of this.staged) {\n const secret = this.secretSpecs.get(field)\n if (secret !== undefined) {\n const value = staged.text.trim()\n if (value !== '') plan.push({ field, run: () => secret.write(value) })\n continue\n }\n const spec = this.spec(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, run: undefined })\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, write.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n return !this.stored(field)\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value)\n return this.userLayer()?.[field] === value\n || (Array.isArray(value) && JSON.stringify(this.userLayer()?.[field]) === JSON.stringify(value))\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.publish()\n }\n\n private spec(field: string): CardFieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error(`im-bridge card has no field ${field}`)\n return spec\n }\n\n private snapshotOf(): SettingsScopeSnapshot<T> {\n return this.scope.getSnapshot()\n }\n\n private sectionValue(field: string): unknown {\n return (this.snapshotOf().value as Record<string, unknown> | undefined)?.[field]\n }\n\n private baseValue(field: string): unknown {\n return (this.snapshotOf().base as Record<string, unknown> | undefined)?.[field]\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.snapshotOf().user as Record<string, unknown> | undefined\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n","/** Staged form over the `im-bridge` settings namespace. */\n\nimport type { SettingsScope, SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport {\n CardForm,\n csvField,\n numberField,\n textField,\n type CardActions,\n type CardFieldState,\n type CardShell,\n} from './card-form.ts'\n\n/** One redacted secret slot from `settings.describe`. */\ninterface SecretSlotView {\n path: readonly string[]\n set: boolean\n}\n\n/**\n * Cross-namespace describe face. Typed locally so this out-of-tree package\n * does not value- or type-import `@deepseek-ai/dsh-client-ui-settings`.\n */\ninterface SettingsDescribeFace {\n getSnapshot(): {\n view?: {\n namespaces: ReadonlyArray<{\n ns: string\n secrets: readonly SecretSlotView[]\n }>\n }\n }\n}\n\n/** Settings namespace paired with this card. */\nconst NS = 'im-bridge'\n\n/** User-editable slice of the im-bridge settings namespace. */\nexport interface WecomCardSettings {\n allowFrom?: string[]\n agentTimeoutSec?: number\n startHint?: string\n deniedMessage?: string\n welcomeMessage?: string\n provider?: string\n model?: string\n}\n\n/** Snapshot the WeCom card renders. */\nexport interface WecomCardState extends CardShell {\n botId: CardFieldState\n secret: CardFieldState\n botIdConfigured: boolean\n secretConfigured: boolean\n allowFrom: CardFieldState\n agentTimeoutSec: CardFieldState\n startHint: CardFieldState\n deniedMessage: CardFieldState\n welcomeMessage: CardFieldState\n provider: CardFieldState\n model: CardFieldState\n}\n\n/** Face the card's slot registration injects. */\nexport interface WecomCardFace extends CardActions {\n hooks: {\n /** Card snapshot bound by the renderer as useWecomCard. */\n wecomCard: SnapshotStore<WecomCardState>\n }\n}\n\n/** Bridges the `im-bridge` scope onto the staged card form. */\nexport class WecomCardController {\n private readonly form: CardForm<WecomCardSettings>\n private readonly store: SnapshotStore<WecomCardState>\n\n /**\n * @param scope - bound settings scope for the `im-bridge` namespace.\n * @param describe - Host describe face; secret literals never ride it.\n */\n constructor(\n private readonly scope: SettingsScope<WecomCardSettings>,\n private readonly describe: SettingsDescribeFace,\n ) {\n this.form = new CardForm(\n scope,\n [\n csvField('allowFrom'),\n numberField('agentTimeoutSec'),\n textField('startHint'),\n textField('deniedMessage'),\n textField('welcomeMessage'),\n textField('provider'),\n textField('model'),\n ],\n [\n { field: 'botId', write: text => this.writeSecret('botId', text) },\n { field: 'secret', write: text => this.writeSecret('secret', text) },\n ],\n )\n this.store = this.form.bind(() => this.projection())\n }\n\n private projection(): WecomCardState {\n return {\n ...this.form.shell(),\n botId: this.form.field('botId'),\n secret: this.form.field('secret'),\n botIdConfigured: this.secretConfigured('botId'),\n secretConfigured: this.secretConfigured('secret'),\n allowFrom: this.form.field('allowFrom'),\n agentTimeoutSec: this.form.field('agentTimeoutSec'),\n startHint: this.form.field('startHint'),\n deniedMessage: this.form.field('deniedMessage'),\n welcomeMessage: this.form.field('welcomeMessage'),\n provider: this.form.field('provider'),\n model: this.form.field('model'),\n }\n }\n\n /**\n * Whether the Host reports a configured value for one secret slot.\n * @param field - `botId` or `secret`.\n * @returns true when describe lists that slot as set.\n */\n private secretConfigured(field: string): boolean {\n const row = this.describe.getSnapshot().view?.namespaces.find(candidate => candidate.ns === NS)\n return row?.secrets.some(slot => slot.path[0] === field && slot.set) === true\n }\n\n /**\n * Write one credential into the user layer, then read configured state back.\n * @param field - `botId` or `secret`.\n * @param text - the staged literal.\n * @returns whether describe reports the slot set afterwards.\n */\n private async writeSecret(field: string, text: string): Promise<boolean> {\n await this.scope.set(field, text)\n return this.secretConfigured(field)\n }\n\n /** Face the slot registration injects. */\n inject(): WecomCardFace {\n return { hooks: { wecomCard: this.store }, ...this.form.actions() }\n }\n}\n","/** Dictionary keys owned by the im-bridge settings card. */\nexport type ImBridgeLocaleKey =\n | 'title'\n | 'description'\n | 'unsaved'\n | 'readOnly'\n | 'saveFailed'\n | 'save'\n | 'saving'\n | 'discard'\n | 'expand'\n | 'collapse'\n | 'overridden'\n | 'reset'\n | 'invalidNumber'\n | 'botId'\n | 'secret'\n | 'secretHint'\n | 'secretConfigured'\n | 'secretUnset'\n | 'allowFrom'\n | 'allowFromHint'\n | 'agentTimeoutSec'\n | 'agentTimeoutSecHint'\n | 'startHint'\n | 'startHintHint'\n | 'deniedMessage'\n | 'deniedMessageHint'\n | 'welcomeMessage'\n | 'welcomeMessageHint'\n | 'provider'\n | 'providerHint'\n | 'model'\n | 'modelHint'\n\n/** English copy for the im-bridge card. */\nexport const en: Record<ImBridgeLocaleKey, string> = {\n title: 'WeCom Bridge',\n description: 'Credentials, allow-list, timeouts, and WeCom-only model overrides.',\n unsaved: 'Unsaved',\n readOnly: 'This document is read-only.',\n saveFailed: 'Save did not land. Correct the fields and try again.',\n save: 'Save',\n saving: 'Saving…',\n discard: 'Discard',\n expand: 'Show settings',\n collapse: 'Hide settings',\n overridden: 'Overridden',\n reset: 'Reset',\n invalidNumber: 'Enter a finite number.',\n botId: 'Bot ID',\n secret: 'Secret',\n secretHint: 'Leave blank to keep the stored value. Save, then restart the process to open the WebSocket.',\n secretConfigured: 'Configured',\n secretUnset: 'Not configured',\n allowFrom: 'Allowed sender userids',\n allowFromHint: 'Comma-separated. Empty allows everyone.',\n agentTimeoutSec: 'Task timeout (seconds)',\n agentTimeoutSecHint: 'Progress bar and remaining-time estimate.',\n startHint: 'Placeholder while thinking',\n startHintHint: 'First stream line after a message arrives.',\n deniedMessage: 'Denied-sender reply',\n deniedMessageHint: 'Sent when the userid is outside the allow-list.',\n welcomeMessage: 'Welcome message',\n welcomeMessageHint: 'Sent when a user opens the WeCom chat.',\n provider: 'WeCom-only provider',\n providerHint: 'Empty follows the GUI default model. Both provider and model must be set to override.',\n model: 'WeCom-only model',\n modelHint: 'Takes effect only together with provider.',\n}\n\n/** Chinese copy for the im-bridge card. */\nexport const zh: Record<ImBridgeLocaleKey, string> = {\n title: '企业微信桥接',\n description: '凭证、白名单、超时和企微专用模型覆盖。',\n unsaved: '未保存',\n readOnly: '当前文档不可写。',\n saveFailed: '保存未生效,请修正后重试。',\n save: '保存',\n saving: '保存中…',\n discard: '放弃',\n expand: '展开设置',\n collapse: '收起设置',\n overridden: '已覆盖',\n reset: '重置',\n invalidNumber: '请输入有效数字。',\n botId: 'Bot ID',\n secret: 'Secret',\n secretHint: '留空保留已存值。保存后需重启进程才会连 WebSocket。',\n secretConfigured: '已配置',\n secretUnset: '未配置',\n allowFrom: '允许的发送者 userid',\n allowFromHint: '逗号分隔;空 = 允许所有人。',\n agentTimeoutSec: '单任务超时(秒)',\n agentTimeoutSecHint: '动画进度条和剩余估算的基准。',\n startHint: '开始处理时的占位提示',\n startHintHint: '收到消息后推送的第一条流式文案。',\n deniedMessage: '非白名单拒绝文案',\n deniedMessageHint: '发送者不在白名单时回复。',\n welcomeMessage: '进入会话欢迎语',\n welcomeMessageHint: '用户打开企微会话时发送。',\n provider: '企微专用 provider',\n providerHint: '空 = 跟随 GUI 默认模型。须与 model 同时填写才覆盖。',\n model: '企微专用 model',\n modelHint: '仅在同时填写 provider 时生效。',\n}\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'im-bridge': ImBridgeLocaleKey\n }\n}\n","/**\n * Browser half: Settings card keyed by the `im-bridge` namespace.\n */\n\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\n// Type-only: ctx.settingsScope.describe and the keyed slot declaration.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { WecomCard } from './WecomCard.tsx'\nimport { WecomCardController } from './card-controller.ts'\nimport { en, zh } from './locales.ts'\n\n/** Settings namespace shared with the Host half. */\nconst NS = 'im-bridge'\n\n/** Required browser services. */\nexport const inject = ['slots', 'locale', 'connection', 'remote', 'settingsScope']\n\n/**\n * Register locale copy and the Plugins-tab card.\n * @param ctx - browser plugin context.\n */\nexport function apply(ctx: ClientContext): void {\n const card = new WecomCardController(\n ctx.settingsScope.bind({ namespace: NS }),\n ctx.settingsScope.describe(),\n )\n\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'im-bridge: locale dicts')\n\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: NS,\n locale: NS,\n inject: () => card.inject(),\n }, WecomCard))\n}\n"],"mappings":"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"}