dsh-client-auto-continue 0.10.2 → 0.11.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 +2 -0
- package/README.zh.md +2 -0
- package/lib/client.js +760 -348
- package/lib/client.js.map +2 -2
- package/lib/types/client/locales.d.ts +17 -0
- package/package.json +2 -2
- package/src/client/locales.ts +36 -2
- package/src/client/settings-card.tsx +420 -265
- package/src/client/styles.ts +259 -17
package/lib/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["src/client/index.ts", "src/shared/core.ts", "src/client/locales.ts", "src/client/settings-card.tsx", "src/client/dsh-store-compat.ts", "src/client/bridge.ts", "src/client/settings-form.ts", "src/client/styles.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Auto-continue plugin, browser half (thin shell).\n *\n * Since 0.8.0 the auto-continue ENGINE runs inside the host process (single\n * instance — see src/host/engine.ts), so this half only:\n * - registers the `auto-continue` settings card (`settings.plugin.item`),\n * - subscribes to the host status bridge (SSE) and shows browser\n * notifications with action buttons (Resume now / Pause 1h) via the bridge\n * action endpoint,\n * - feeds the card's stats / paused-sessions panels from the bridge state.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis';\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client';\n// Type-only: pulls the settings-surface SlotMap merge and ctx.settingsScope.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client';\n// Type-only: pulls the `settings.plugin.item` SlotMap merge.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client';\nimport { type AutoContinueSettings } from './engine.ts';\nimport { en, zh, type SettingsCardKey } from './locales.ts';\nimport {\n AutoContinueSettingsCard,\n AutoContinueSettingsCardController,\n} from './settings-card.tsx';\nimport { startBridge } from './bridge.ts';\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'auto-continue';\n\n/** Settings namespace the settings card edits (the host engine reads it). */\nconst SETTINGS_NS = 'auto-continue';\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** auto-continue settings-card copy. */\n 'auto-continue': SettingsCardKey;\n }\n}\n\n/** Services required by this plugin. */\nexport const inject = ['slots', 'locale', 'settingsScope'];\n\n// 浏览器侧辅助(设置卡片用): 桥状态读取与暂停解除。\nexport {\n pausedSessions,\n readTodayStats,\n resetTodayStats,\n unpauseSession,\n} from './bridge.ts';\n\n/**\n * Plugin body: settings card + host status bridge (notifications, stats,\n * paused sessions).\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'auto-continue: dictionaries');\n\n const scope = ctx.settingsScope.bind<AutoContinueSettings>({ namespace: SETTINGS_NS });\n const syncLocale = (): void => {\n const active = ctx.locale.getLocale().active;\n const snapshot = scope.getSnapshot();\n if (snapshot.status !== 'ready' || !snapshot.writable || snapshot.mode !== 'host') return;\n if (snapshot.value?.locale === active) return;\n void scope.set('locale', active);\n };\n ctx.effect(() => scope.subscribe(syncLocale), 'auto-continue: locale settings sync');\n ctx.on('locale/change', syncLocale);\n syncLocale();\n\n // 状态桥: 订阅 host 的通知与运行时状态, 弹浏览器通知并驱动卡片面板。\n ctx.effect(() => startBridge(), 'auto-continue: host bridge');\n\n // Plugin configuration card: one staged form over the `auto-continue`\n // settings namespace, contributed to the plugin-configuration section\n // (Settings → Plugins). Since DSH 0.1.0-rc.7 `settings.plugin.item` is a\n // keyed slot dispatched by the settings namespace it edits, so the entry\n // registers with `key` (the namespace), like the official cards.\n const controller = new AutoContinueSettingsCardController(scope);\n ctx.slots.inject('settings.plugin.item', () =>\n ctx.slots.register(\n {\n name: 'settings.plugin.item',\n key: SETTINGS_NS,\n locale: NS,\n inject: () => controller.inject(),\n },\n AutoContinueSettingsCard,\n ),\n );\n}\n", "/** 共享核心: 平台无关的纯逻辑与类型。\n *\n * 被 host 引擎(src/host/engine.ts)与浏览器半侧共用: 配置解析、错误分类、\n * 模板填充、自适应退避、幂等护栏的工具结果提取、循环守卫的会话状态机,\n * 以及回显识别。引擎迁入 host 后(0.8.0), 浏览器半侧只 re-export 本模块。\n */\nimport type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session/types';\n\n/** Supported UI/config locales. Any unknown browser locale falls back to Chinese. */\nexport type AutoContinueLocale = 'en' | 'zh';\n\n/** Locale-owned defaults for the user-editable text fields. */\nexport const LOCALIZED_TEXT_DEFAULTS = {\n zh: {\n continueText: '继续',\n continueTextMaxTokens: '继续',\n guardPendingText: '(上一步工具「{tool}」可能未完成, 先确认状态再继续, 不要重复执行)',\n guardDoneText: '(上一步工具「{tool}」已完成, 结果: {result}; 不要重复执行, 直接继续)',\n loopText: '(检测到你可能陷入循环, 请停止重复刚才的动作, 换一种方式继续)',\n },\n en: {\n continueText: 'Continue',\n continueTextMaxTokens: 'Continue',\n guardPendingText:\n '(The previous tool \"{tool}\" may not have completed. Check its state before continuing and do not run it again.)',\n guardDoneText:\n '(The previous tool \"{tool}\" completed successfully. Result: {result}; do not run it again. Continue from there.)',\n loopText:\n '(You may be stuck in a loop. Stop repeating the last action and continue with a different approach.)',\n },\n} as const satisfies Record<AutoContinueLocale, Record<string, string>>;\n\n/** The `auto-continue` settings section (all fields optional on the wire; the host schema carries defaults). */\nexport interface AutoContinueSettings {\n /** Active browser/UI locale mirrored by the client. */\n locale?: AutoContinueLocale;\n /** Text automatically sent after an interruption. */\n continueText?: string;\n /** Text sent when the output token ceiling is reached (same placeholders as `continueText`). */\n continueTextMaxTokens?: string;\n /** Idempotency guard: inspect the last tool call before resuming and steer the model. */\n guardTools?: boolean;\n /** Guard text appended when the last tool call has no confirmed result (it may have partially executed). */\n guardPendingText?: string;\n /** Guard text appended when the last tool call completed successfully (don't rerun it). */\n guardDoneText?: string;\n /** Grace period after an interruption before auto-sending (ms). */\n graceMs?: number;\n /** Minimum interval between two auto-continues per session (ms). */\n cooldownMs?: number;\n /** Max consecutive auto-continues per session before stopping. */\n maxConsecutive?: number;\n /** Scan recently interrupted sessions on page load / reconnect. */\n scanOnBoot?: boolean;\n /** Max sessions the scan checks (most recently updated). */\n scanLimit?: number;\n /** Scan only considers interruptions inside this window (ms). */\n freshMs?: number;\n /** Log `[auto-continue]` lines to the browser console. */\n verbose?: boolean;\n /** Classify failures: auto-continue transient errors only; permanent ones (auth/balance/model) are skipped and notified. */\n classify?: boolean;\n /** Provider-specific message/code/status fragments that explicitly count as retryable, one literal per line. */\n retryableErrorPatterns?: string;\n /** Cooldown multiplier per consecutive failure (adaptive backoff). */\n backoffFactor?: number;\n /** Cap on the effective backoff interval (ms). */\n backoffMaxMs?: number;\n /** Show browser notifications for auto-continue events. */\n notify?: boolean;\n /** Globally pause auto-continue: no live or scan send, queued pending sends cancelled. */\n paused?: boolean;\n /** Loop guard: detect a running turn spinning in place (short talk without tools, or the same tool repeating) and restart it. */\n loopGuard?: boolean;\n /** A model message shorter than this many chars counts as a \"short sentence\" (loop signal). */\n loopShortChars?: number;\n /** Consecutive short sentences within this window (ms) with no tool call in between trip the loop guard. */\n loopWindowMs?: number;\n /** Consecutive short sentences trip the loop guard. */\n loopShortCount?: number;\n /** Consecutive identical tool calls with identical arguments AND identical results trip the loop guard. */\n loopToolRepeat?: number;\n /** Consecutive identical short sentences trip the loop guard (strongest spinning signal). */\n loopRepeatText?: number;\n /** Text sent after the loop guard cancels and restarts a turn (supports {tool}). */\n loopText?: string;\n}\n\n/** Fully resolved configuration (built-in defaults + user overrides). */\nexport type AutoContinueConfig = Required<AutoContinueSettings>;\n\n/** Effective built-in defaults; localized text fields use Chinese until a browser locale is mirrored. */\nexport const DEFAULT_CONFIG: AutoContinueConfig = {\n locale: 'zh',\n ...LOCALIZED_TEXT_DEFAULTS.zh,\n guardTools: true,\n graceMs: 3000,\n cooldownMs: 20000,\n maxConsecutive: 3,\n scanOnBoot: true,\n scanLimit: 8,\n freshMs: 15 * 60 * 1000,\n verbose: true,\n classify: true,\n retryableErrorPatterns: '',\n backoffFactor: 2,\n backoffMaxMs: 300000,\n notify: false,\n paused: false,\n loopGuard: true,\n loopShortChars: 40,\n loopWindowMs: 30000,\n loopShortCount: 12,\n loopRepeatText: 4,\n loopToolRepeat: 5,\n};\n\nfunction numberOr(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback;\n}\n\nfunction booleanOr(value: unknown, fallback: boolean): boolean {\n return typeof value === 'boolean' ? value : fallback;\n}\n\n/** Resolve a (possibly partial / not-yet-loaded) settings section to a full config. */\nexport function resolveConfig(section: AutoContinueSettings | undefined): AutoContinueConfig {\n const value = section ?? {};\n const locale: AutoContinueLocale = value.locale === 'en' ? 'en' : 'zh';\n const localized = LOCALIZED_TEXT_DEFAULTS[locale];\n const text =\n typeof value.continueText === 'string' && value.continueText.trim() !== ''\n ? value.continueText\n : localized.continueText;\n const maxTokensText =\n typeof value.continueTextMaxTokens === 'string' && value.continueTextMaxTokens.trim() !== ''\n ? value.continueTextMaxTokens\n : localized.continueTextMaxTokens;\n const guardPendingText =\n typeof value.guardPendingText === 'string' && value.guardPendingText.trim() !== ''\n ? value.guardPendingText\n : localized.guardPendingText;\n const guardDoneText =\n typeof value.guardDoneText === 'string' && value.guardDoneText.trim() !== ''\n ? value.guardDoneText\n : localized.guardDoneText;\n return {\n locale,\n continueText: text,\n continueTextMaxTokens: maxTokensText,\n guardTools: booleanOr(value.guardTools, DEFAULT_CONFIG.guardTools),\n guardPendingText,\n guardDoneText,\n graceMs: numberOr(value.graceMs, DEFAULT_CONFIG.graceMs),\n cooldownMs: numberOr(value.cooldownMs, DEFAULT_CONFIG.cooldownMs),\n maxConsecutive: Math.max(1, numberOr(value.maxConsecutive, DEFAULT_CONFIG.maxConsecutive)),\n scanOnBoot: booleanOr(value.scanOnBoot, DEFAULT_CONFIG.scanOnBoot),\n scanLimit: Math.max(1, numberOr(value.scanLimit, DEFAULT_CONFIG.scanLimit)),\n freshMs: numberOr(value.freshMs, DEFAULT_CONFIG.freshMs),\n verbose: booleanOr(value.verbose, DEFAULT_CONFIG.verbose),\n classify: booleanOr(value.classify, DEFAULT_CONFIG.classify),\n retryableErrorPatterns:\n typeof value.retryableErrorPatterns === 'string'\n ? value.retryableErrorPatterns.trim()\n : DEFAULT_CONFIG.retryableErrorPatterns,\n backoffFactor: Math.max(1, numberOr(value.backoffFactor, DEFAULT_CONFIG.backoffFactor)),\n backoffMaxMs: numberOr(value.backoffMaxMs, DEFAULT_CONFIG.backoffMaxMs),\n notify: booleanOr(value.notify, DEFAULT_CONFIG.notify),\n paused: booleanOr(value.paused, DEFAULT_CONFIG.paused),\n loopGuard: booleanOr(value.loopGuard, DEFAULT_CONFIG.loopGuard),\n loopShortChars: Math.max(1, numberOr(value.loopShortChars, DEFAULT_CONFIG.loopShortChars)),\n loopWindowMs: Math.max(1000, numberOr(value.loopWindowMs, DEFAULT_CONFIG.loopWindowMs)),\n loopShortCount: Math.max(2, numberOr(value.loopShortCount, DEFAULT_CONFIG.loopShortCount)),\n loopRepeatText: Math.max(2, numberOr(value.loopRepeatText, DEFAULT_CONFIG.loopRepeatText)),\n loopToolRepeat: Math.max(2, numberOr(value.loopToolRepeat, DEFAULT_CONFIG.loopToolRepeat)),\n loopText:\n typeof value.loopText === 'string' && value.loopText.trim() !== ''\n ? value.loopText\n : localized.loopText,\n };\n}\n\n/**\n * 视为「非人为中断」的回合结束原因, 用于启动/重连扫描。\n * - `interrupted` 只由崩溃修复在宿主重载时写入(loop 永不实时发出), 因此仅在扫描路径处理;\n * - 实时事件路径只对 `error` / `max-tokens` 自动续跑;\n * - `aborted`(用户停止)与 `blocked`(策略拒绝)永不自动继续。\n */\ntype NonHumanReason = 'error' | 'interrupted' | 'max-tokens';\n\nexport function isNonHumanReason(kind: string): kind is NonHumanReason {\n return kind === 'error' || kind === 'interrupted' || kind === 'max-tokens';\n}\n\n/** 一次回合失败的机器可读事实(turn/end error 的 LlmFailure 载荷)。 */\nexport interface FailureFacts {\n /** 稳定机器路由码(如 UPSTREAM、RATE_LIMIT_EXCEEDED、INVALID_API_KEY)。 */\n code: string;\n /** 人类可读的失败描述。 */\n message: string;\n /** 供应商 HTTP 状态码(可用时)。 */\n status?: number;\n}\n\n/**\n * 错误分类: 该失败是否值得自动继续。\n * 用户填写的 provider 专属文本片段优先覆盖内置结果; 未命中时,\n * 永久性失败(认证/余额/模型不存在/上下文超限等)重试也不会成功, 应跳过并通知用户;\n * 其余(网络、超时、5xx、429 等)视为临时性失败, 允许自动恢复。\n */\nexport function isTransientFailure(failure: FailureFacts, retryableErrorPatterns = ''): boolean {\n const haystack = `${failure.code} ${failure.status ?? ''} ${failure.message}`.toLowerCase();\n const explicitlyRetryable = retryableErrorPatterns\n .split(/\\r?\\n/)\n .map((pattern) => pattern.trim().toLowerCase())\n .filter((pattern) => pattern !== '')\n .some((pattern) => haystack.includes(pattern));\n if (explicitlyRetryable) return true;\n const status = failure.status;\n if (status !== undefined && (status === 401 || status === 403)) return false;\n const permanent =\n /auth|unauthor|forbidden|credential|api[_-]?key|permission/i.test(haystack) ||\n /insufficient.*(balance|quota)|billing|payment|quota.*exceeded.*(?!retry)/i.test(haystack) ||\n /model.*not[_-]?found|unknown[_-]?model|model[_-]?not[_-]?found|not.*support.*model/i.test(haystack) ||\n /context.*(length|limit|overflow|exceed)|token.*limit|max.*context/i.test(haystack) ||\n /invalid[_-]?request|bad[_-]?request/i.test(haystack);\n return !permanent;\n}\n\n/**\n * host/agent-error 消息分类: 仅明确属于网络/传输类的临时错误才自动继续。\n * 其余(序列化失败、配置/宿主内部错误等)视为永久性——重试无益, 且用户停止导致的\n * 序列化失败(如 Windows 下 abort 的 DOMException reason)绝不能自动续跑。\n */\nexport function isTransientAgentError(message: string): boolean {\n return /network|timeout|timed ?out|econn|etimedout|socket|5\\d\\d|\\b429\\b|upstream|temporar/i.test(message);\n}\n\n/** 通知上的一个操作按钮(action 标识 + 显示文案)。 */\nexport interface NotifyAction {\n /** 稳定动作标识, 点击时经 onAction 回调传出。 */\n action: string;\n /** 按钮显示文案。 */\n title: string;\n}\n\n/** 通知的可选行为: 操作按钮列表与点击回调。 */\nexport interface NotifyOptions {\n actions?: NotifyAction[];\n onAction?: (action: string) => void;\n}\n\n/** 浏览器通知(不可用时静默跳过); 点击通知聚焦窗口, 操作按钮走 onAction。 */\n/** 把毫秒格式化为人类可读的经过时长(如 65s → 1m5s)。 */\nfunction formatElapsed(ms: number | undefined): string {\n if (ms === undefined || !Number.isFinite(ms) || ms < 0) return '';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const s = Math.round(ms / 1000);\n if (s < 60) return `${s}s`;\n return `${Math.floor(s / 60)}m${s % 60 > 0 ? `${s % 60}s` : ''}`;\n}\n\n/** 模板填充所需的上下文(全部可选, 缺失的占位符填为空串)。 */\nexport interface TemplateContext {\n /** 失败事实(错误码/消息/HTTP 状态), 对应 {code}/{message}/{status}。 */\n facts?: FailureFacts;\n /** 失败前最后一次工具调用的名称, 对应 {tool}。 */\n tool?: string;\n /** 失败回合的编号, 对应 {turn}。 */\n turn?: number;\n /** 连续失败次数(含本次), 对应 {errorCount}。 */\n errorCount?: number;\n /** 会话标题(来自 session.list 投影, 可用时), 对应 {sessionTitle}。 */\n sessionTitle?: string;\n /** 自失败发生以来的毫秒数, 对应 {elapsed}。 */\n elapsedMs?: number;\n /** 上一步工具结果摘要(截断), 对应 {result}(护栏模板用)。 */\n result?: string;\n}\n\n/** 用失败事实与回合信息填充 continueText 模板占位符({code}/{message}/{status}/{tool}/{turn}/{errorCount}/{sessionTitle}/{elapsed}/{result})。 */\nexport function fillTemplate(template: string, ctx: TemplateContext): string {\n return template\n .replace(/\\{code\\}/g, ctx.facts?.code ?? '')\n .replace(/\\{message\\}/g, ctx.facts?.message ?? '')\n .replace(/\\{status\\}/g, ctx.facts?.status !== undefined ? String(ctx.facts.status) : '')\n .replace(/\\{tool\\}/g, ctx.tool ?? '')\n .replace(/\\{turn\\}/g, ctx.turn !== undefined ? String(ctx.turn) : '')\n .replace(/\\{errorCount\\}/g, ctx.errorCount !== undefined ? String(ctx.errorCount) : '')\n .replace(/\\{sessionTitle\\}/g, ctx.sessionTitle ?? '')\n .replace(/\\{elapsed\\}/g, formatElapsed(ctx.elapsedMs))\n .replace(/\\{result\\}/g, ctx.result ?? '');\n}\n\n// ---------- 幂等护栏: 上一步工具调用的执行状态 ----------\n\n/** 工具结果摘要的最大长度(护栏模板 {result} 用)。 */\nconst TOOL_RESULT_CAP = 160;\n\n/** 从任意内容块里递归收集文本(结果为模型可见的工具输出)。 */\nfunction extractText(blocks: unknown, cap: number): string {\n let out = '';\n const walk = (value: unknown): void => {\n if (out.length >= cap) return;\n if (Array.isArray(value)) {\n for (const item of value) walk(item);\n return;\n }\n if (typeof value !== 'object' || value === null) return;\n const record = value as Record<string, unknown>;\n if (record['type'] === 'text' && typeof record['text'] === 'string') {\n out += record['text'];\n return;\n }\n for (const child of Object.values(record)) walk(child);\n };\n walk(blocks);\n return out.slice(0, cap);\n}\n\n/** 上一步工具调用的判定结果: 是否已确认完成, 以及文本摘要。 */\nexport interface ToolResultFacts {\n /** 工具是否成功完成(内部失败或 isError 视为未成功)。 */\n ok: boolean;\n /** 工具输出的文本摘要(截断)。 */\n excerpt: string;\n}\n\n/** 从 tool/result 事件载荷提取成功与否与文本摘要。 */\nexport function toolResultFacts(data: {\n error?: { name?: string; code?: string };\n message?: { content?: Array<{ type?: string; content?: unknown; isError?: boolean }> };\n}): ToolResultFacts {\n const failed = data.error !== undefined || data.message?.content?.[0]?.isError === true;\n return { ok: !failed, excerpt: extractText(data.message?.content?.[0]?.content, TOOL_RESULT_CAP) };\n}\n\n/** 自适应退避: 同一会话连续失败时的有效冷却间隔。 */\nexport function effectiveCooldown(\n consecutive: number,\n base: number,\n factor: number,\n max: number,\n): number {\n // consecutive = 已连续自动继续的次数; 第 1 次后开始按 factor 递增\n const multiplier = Math.pow(factor, consecutive);\n return Math.min(Math.max(base, base * multiplier), Math.max(base, max));\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** 浏览器当前 IANA 时区; 不可用时省略(宿主允许省略)。 */\nfunction clientTimeZone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || undefined;\n } catch {\n return undefined;\n }\n}\n\n/** 一天的自动继续统计(host 单实例内存态)。 */\nexport interface DayStats {\n /** 本地日期 YYYY-MM-DD。 */\n date: string;\n /** 自动发送次数。 */\n sent: number;\n /** 因永久性错误跳过的次数。 */\n skipped: number;\n /** 发送后回合成功完成(恢复成功)的次数。 */\n recovered: number;\n /** 发送后再次失败的次数。 */\n failed: number;\n /** 达到连续上限而停止的次数(按停止事件计)。 */\n gaveUp: number;\n /** loop guard 打断并重启回合的次数。 */\n looped: number;\n /** 按错误码计数的失败分布。 */\n byCode: Record<string, number>;\n}\n\nexport function todayKey(): string {\n const d = new Date();\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n return `${d.getFullYear()}-${mm}-${dd}`;\n}\n\n/** 空统计桶。 */\nexport function emptyDayStats(): DayStats {\n return { date: todayKey(), sent: 0, skipped: 0, recovered: 0, failed: 0, gaveUp: 0, looped: 0, byCode: {} };\n}\n\n/** 每会话运行时状态。 */\nexport interface SessionState {\n /** 连续自动「继续」次数; 成功回合或用户手动介入后归零。 */\n consecutive: number;\n /** 上次自动「继续」时间戳。 */\n lastAutoAt: number;\n /** 上次自动「继续」尝试(成功或失败)时间戳; 防止失败场景下的快速重试循环。 */\n lastAttemptAt: number;\n /** 我们上次自动发送的文本(用于识别自己的回显)。 */\n lastSentText: string;\n /** 宽限期定时器(进行中的待发送)。 */\n pendingTimer: ReturnType<typeof setTimeout> | undefined;\n /** 宿主权威 running 位(来自 host/session-status 与回合事件)。 */\n running: boolean | undefined;\n /** 当前排队消息数(来自 session/queue 帧)。 */\n queued: number;\n /** 子代理会话(host/session-added 带 parentSessionId)。 */\n subagent: boolean;\n /** 最近一次回合失败的事实(用于分类与模板填充)。 */\n lastFailure: FailureFacts | undefined;\n /** 最近一次失败的发生时间(模板 {elapsed} 与恢复统计用)。 */\n lastFailureAt: number;\n /** 失败前最后一次工具调用的名称(模板 {tool} 与幂等护栏用)。 */\n lastTool: string | undefined;\n /** 上一步工具调用的结果状态: 'pending' = 已发起未见结果(可能已部分执行)。 */\n lastToolResult: 'pending' | ToolResultFacts | undefined;\n /** 失败回合的编号(模板 {turn})。 */\n lastTurn: number | undefined;\n /** 我们最近一次自动发送的时间戳; 0 = 没有待确认的恢复。 */\n pendingRecoveryAt: number;\n /** 当前连续短句数(loop guard 信号 1: 空转)。 */\n shortRun: number;\n /** 最后一条短句的时间(时间窗判定用)。 */\n lastShortAt: number;\n /** 最后一条模型消息的文本(相同文本重复判定用)。 */\n lastAssistantText: string;\n /** 连续相同文本消息数(最强空转信号, 不限长度)。 */\n sameTextRun: number;\n /**\n * 工具重复信号(loop guard 信号 2: 死循环)。\n * 只有「同工具 + 同参数 + 同结果」的连续调用才累计; 参数或结果有变化视为有进展, 计数重置。\n */\n toolRun:\n | {\n /** 工具名 + 参数(用于判定是否同一调用)。 */\n key: string;\n /** 连续相同调用数(结果确认后更新)。 */\n count: number;\n /** 上次该调用的结果摘要(比较用)。 */\n lastResult: string | undefined;\n /** 本次调用等待结果确认。 */\n waiting: boolean;\n }\n | undefined;\n /** 本回合已触发过 loop guard(防重复打断)。 */\n loopFired: boolean;\n /** loop 重启的延迟定时器(冷却结束后再 schedule)。 */\n loopRetryTimer: ReturnType<typeof setTimeout> | undefined;\n /** 我们主动 cancel 过本回合(区分用户停止)。 */\n loopCancelled: boolean;\n}\n\nexport const freshState = (): SessionState => ({\n consecutive: 0,\n lastAutoAt: 0,\n lastAttemptAt: 0,\n lastSentText: '',\n pendingTimer: undefined,\n running: undefined,\n queued: 0,\n subagent: false,\n lastFailure: undefined,\n lastFailureAt: 0,\n lastTool: undefined,\n lastToolResult: undefined,\n lastTurn: undefined,\n pendingRecoveryAt: 0,\n shortRun: 0,\n lastShortAt: 0,\n lastAssistantText: '',\n sameTextRun: 0,\n toolRun: undefined,\n loopFired: false,\n loopCancelled: false,\n loopRetryTimer: undefined,\n});\n\n\nexport const RECOVERY_WINDOW_MS = 10 * 60 * 1000;\n\nexport const ECHO_WINDOW_MS = 10 * 60 * 1000;\n\nexport function isOurEcho(state: SessionState, event: SessionEvent): boolean {\n if (event.type !== 'user/message') return false;\n const message = event.data;\n if (message.source.kind !== 'user') return false;\n if (state.lastSentText === '') return false;\n if (Date.now() - state.lastAutoAt > ECHO_WINDOW_MS) return false;\n const text = message.content\n .filter((part): part is { type: 'text'; text: string } => part.type === 'text')\n .map((part) => part.text)\n .join('');\n return text === state.lastSentText;\n}\n", "/**\n * `auto-continue` namespace dictionaries: copy for the plugin settings card\n * registered into the `settings.plugin.item` seat of the plugin-configuration\n * section. Includes the card-chrome keys the card component reads.\n */\nimport { LOCALIZED_TEXT_DEFAULTS } from '../shared/core.ts';\n\n/** 简体中文词典(键集的事实来源)。 */\nexport const zh = {\n 'card.title': '自动继续',\n 'card.description': '请求因网络等原因(非人为)中断后, 自动发送「继续」续跑。',\n 'field.paused': '暂停自动继续',\n 'field.pausedHint': '全局暂停: 实时与扫描都不会再自动发送, 已排队的待发送也会取消。',\n 'field.continueText': '继续文本',\n 'field.continueTextHint': '中断后自动发送的消息内容。',\n 'default.continueText': LOCALIZED_TEXT_DEFAULTS.zh.continueText,\n 'field.continueTextMaxTokens': '超限时的继续文本',\n 'field.continueTextMaxTokensHint': '达到输出 token 上限时自动发送的文本, 支持与继续文本相同的占位符。',\n 'default.continueTextMaxTokens': LOCALIZED_TEXT_DEFAULTS.zh.continueTextMaxTokens,\n 'field.guardTools': '幂等护栏',\n 'field.guardToolsHint': '续跑前检查上一步工具调用: 结果未确认时提示先确认状态, 已成功时提示不要重复执行, 避免重复 commit/调 API。',\n 'field.guardPendingText': '结果未确认时的护栏文本',\n 'field.guardPendingTextHint': '上一步工具可能已部分执行时附加到继续文本之后, 支持 {tool} 占位符。',\n 'default.guardPendingText': LOCALIZED_TEXT_DEFAULTS.zh.guardPendingText,\n 'field.guardDoneText': '工具已成功时的护栏文本',\n 'field.guardDoneTextHint': '上一步工具已确认成功时附加到继续文本之后, 支持 {tool} 与 {result}(结果摘要)占位符。',\n 'default.guardDoneText': LOCALIZED_TEXT_DEFAULTS.zh.guardDoneText,\n 'field.graceMs': '宽限期 (ms)',\n 'field.graceMsHint': '检测到中断后等待的时长; 期间宿主自行恢复则取消。',\n 'field.cooldownMs': '冷却时间 (ms)',\n 'field.cooldownMsHint': '同一会话两次自动「继续」的最小间隔, 失败尝试也计入。',\n 'field.maxConsecutive': '最大连续次数',\n 'field.maxConsecutiveHint': '同一会话连续自动「继续」的上限; 超过后停止, 直到用户手动介入或出现成功回合。',\n 'field.scanOnBoot': '启动/重连扫描',\n 'field.scanOnBootHint': '页面启动或重连时扫描最近中断的会话并自动续跑(如浏览器关闭期间宿主崩溃)。',\n 'field.scanLimit': '扫描会话数',\n 'field.scanLimitHint': '最多检查多少个最近更新的会话(不含运行中与子代理会话)。',\n 'field.freshMs': '扫描时间窗 (ms)',\n 'field.freshMsHint': '扫描只处理该时间窗内的中断。',\n 'field.verbose': '详细日志',\n 'field.verboseHint': '在浏览器控制台输出 [auto-continue] 日志。',\n 'field.classify': '错误分类',\n 'field.classifyHint': '仅自动恢复临时性错误(网络/超时/5xx 等); 认证/余额/模型不存在等永久性错误跳过并通知。',\n 'field.retryableErrorPatterns': '自定义可恢复错误',\n 'field.retryableErrorPatternsHint': '每行一个大小写不敏感的普通文本片段; 命中错误码、HTTP 状态或消息时覆盖内置分类。请只填 provider 稳定且足够具体的文案, 过宽会重复请求。',\n 'field.backoffFactor': '退避系数',\n 'field.backoffFactorHint': '连续失败时冷却间隔的倍率(如 2 表示 20s→40s→80s 递增)。',\n 'field.backoffMaxMs': '最大退避间隔 (ms)',\n 'field.backoffMaxMsHint': '自适应退避的上限, 防止等待过久。',\n 'field.notify': '浏览器通知',\n 'field.notifyHint': '自动继续成功/放弃/遇到永久性错误时弹出浏览器通知, 通知带「立即续跑」与「暂停该会话 1 小时」按钮。',\n 'stats.title': '今日统计',\n 'stats.sent': '自动继续',\n 'stats.skipped': '跳过(永久错误)',\n 'stats.recovered': '恢复成功',\n 'stats.failed': '继续后仍失败',\n 'stats.gaveUp': '停止(达上限)',\n 'stats.looped': '循环打断',\n 'field.loopGuard': '循环守卫',\n 'field.loopGuardHint': '检测运行中的回合空转: 连续短句且无工具调用, 或连续调用相同工具时, 自动取消并用循环提示文本重启回合。',\n 'field.loopShortChars': '短句长度上限 (字符)',\n 'field.loopShortCharsHint': '模型消息文本短于该值计为一条短句(空转信号)。',\n 'field.loopWindowMs': '短句时间窗 (ms)',\n 'field.loopWindowMsHint': '连续短句必须落在这个时间窗内; 正常思考的短文本散布在长时间里不会被误判。',\n 'field.loopShortCount': '连续短句阈值',\n 'field.loopShortCountHint': '时间窗内连续多少条短句且期间无工具调用时判定空转循环。',\n 'field.loopRepeatText': '相同消息重复次数',\n 'field.loopRepeatTextHint': '连续输出多少条完全相同的消息时判定空转(最强信号, 不限长度, 如模型反复说同一句话)。',\n 'field.loopToolRepeat': '同工具重复次数',\n 'field.loopToolRepeatHint': '同工具+同参数+同结果的连续调用多少次时判定死循环; 参数或结果有变化视为有进展。',\n 'field.loopText': '循环提示文本',\n 'field.loopTextHint': '打断后重启回合时发送的文本, 支持 {tool} 占位符。',\n 'default.loopText': LOCALIZED_TEXT_DEFAULTS.zh.loopText,\n 'stats.byCode': '按错误码统计',\n 'stats.empty': '今天还没有自动继续记录。',\n 'stats.reset': '清零',\n 'pause.title': '已暂停会话',\n 'pause.none': '没有暂停中的会话。',\n 'pause.clearAll': '全部解除',\n 'pause.unpause': '解除',\n 'pause.minutes': '分钟',\n 'chrome.collapse': '收起设置',\n 'chrome.expand': '展开设置',\n 'chrome.unsaved': '未保存',\n 'chrome.readOnly': '当前部署的设置只读。',\n 'chrome.saveFailed': '部署未接受这些值, 已保留供你修改。',\n 'chrome.discard': '放弃',\n 'chrome.saving': '保存中…',\n 'chrome.save': '保存',\n 'chrome.overridden': '已覆盖',\n 'chrome.reset': '恢复默认',\n 'chrome.invalidNumber': '请输入数字, 留空则使用默认值。',\n 'chrome.inherit': '继承',\n 'chrome.on': '开',\n 'chrome.off': '关',\n} satisfies Record<string, string>;\n\n/** 本插件的键联合。 */\nexport type SettingsCardKey = keyof typeof zh;\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en: Record<SettingsCardKey, string> = {\n 'card.title': 'Auto continue',\n 'card.description': 'When a request is interrupted by a non-human cause, automatically send \"Continue\" to resume.',\n 'field.paused': 'Pause auto-continue',\n 'field.pausedHint': 'Globally pause: no live or scan auto-send fires, and queued pending sends are cancelled.',\n 'field.continueText': 'Continue text',\n 'field.continueTextHint': 'Message automatically sent after an interruption.',\n 'default.continueText': LOCALIZED_TEXT_DEFAULTS.en.continueText,\n 'field.continueTextMaxTokens': 'Continue text (max tokens)',\n 'field.continueTextMaxTokensHint': 'Text sent when the output token ceiling is reached; same placeholders as the continue text.',\n 'default.continueTextMaxTokens': LOCALIZED_TEXT_DEFAULTS.en.continueTextMaxTokens,\n 'field.guardTools': 'Idempotency guard',\n 'field.guardToolsHint': 'Before resuming, inspect the last tool call: if its result is unconfirmed, tell the model to check state first; if it succeeded, tell it not to rerun — avoids duplicate commits / API calls.',\n 'field.guardPendingText': 'Guard text (unconfirmed result)',\n 'field.guardPendingTextHint': 'Appended when the last tool may have partially executed; supports the {tool} placeholder.',\n 'default.guardPendingText': LOCALIZED_TEXT_DEFAULTS.en.guardPendingText,\n 'field.guardDoneText': 'Guard text (tool succeeded)',\n 'field.guardDoneTextHint': 'Appended when the last tool is confirmed done; supports {tool} and {result} (result excerpt).',\n 'default.guardDoneText': LOCALIZED_TEXT_DEFAULTS.en.guardDoneText,\n 'field.graceMs': 'Grace period (ms)',\n 'field.graceMsHint': 'Wait after an interruption; cancelled if the host recovers on its own.',\n 'field.cooldownMs': 'Cooldown (ms)',\n 'field.cooldownMsHint': 'Minimum interval between auto-continues per session; failed attempts count too.',\n 'field.maxConsecutive': 'Max consecutive',\n 'field.maxConsecutiveHint': 'Max consecutive auto-continues per session; stops until a user intervenes or a turn completes.',\n 'field.scanOnBoot': 'Scan on load / reconnect',\n 'field.scanOnBootHint': 'Scan recently interrupted sessions on page load or reconnect (e.g. the host crashed while the browser was closed).',\n 'field.scanLimit': 'Scan limit',\n 'field.scanLimitHint': 'How many most-recently-updated sessions to check (running / subagent sessions excluded).',\n 'field.freshMs': 'Scan window (ms)',\n 'field.freshMsHint': 'Only interruptions inside this window are considered.',\n 'field.verbose': 'Verbose logs',\n 'field.verboseHint': 'Log [auto-continue] lines to the browser console.',\n 'field.classify': 'Classify errors',\n 'field.classifyHint': 'Auto-resume transient failures only (network/timeout/5xx…); auth, balance and model errors are skipped and notified.',\n 'field.retryableErrorPatterns': 'Custom retryable errors',\n 'field.retryableErrorPatternsHint': 'One case-insensitive literal per line. A match in the error code, HTTP status, or message overrides built-in classification. Use only stable, provider-specific text; broad matches can repeat requests.',\n 'field.backoffFactor': 'Backoff factor',\n 'field.backoffFactorHint': 'Cooldown multiplier per consecutive failure (2 = 20s→40s→80s…).',\n 'field.backoffMaxMs': 'Max backoff (ms)',\n 'field.backoffMaxMsHint': 'Cap on the adaptive backoff interval.',\n 'field.notify': 'Browser notifications',\n 'field.notifyHint': 'Notify when auto-continue fires, gives up, or hits a permanent error; notifications carry \"Resume now\" and \"Pause this session 1h\" buttons.',\n 'stats.title': \"Today's stats\",\n 'stats.sent': 'Auto-continued',\n 'stats.skipped': 'Skipped (permanent)',\n 'stats.recovered': 'Recovered',\n 'stats.failed': 'Failed after',\n 'stats.gaveUp': 'Gave up (cap)',\n 'stats.looped': 'Loops broken',\n 'field.loopGuard': 'Loop guard',\n 'field.loopGuardHint': 'Detects a running turn spinning in place — many short sentences with no tool calls, or the same tool repeating — cancels it and restarts with the loop text.',\n 'field.loopShortChars': 'Short-sentence max (chars)',\n 'field.loopShortCharsHint': 'A model message shorter than this counts as a short sentence (spinning signal).',\n 'field.loopWindowMs': 'Short-sentence window (ms)',\n 'field.loopWindowMsHint': 'Consecutive short sentences must land inside this window; normal thinking spread over time is not misjudged.',\n 'field.loopShortCount': 'Short-sentence threshold',\n 'field.loopShortCountHint': 'How many consecutive short sentences inside the window, with no tool call, trip the loop guard.',\n 'field.loopRepeatText': 'Identical message count',\n 'field.loopRepeatTextHint': 'How many consecutive identical messages trip the guard (strongest signal, any length, e.g. the model repeating the same line).',\n 'field.loopToolRepeat': 'Same-tool repeat count',\n 'field.loopToolRepeatHint': 'How many consecutive calls of the same tool with identical arguments and results trip the loop guard; a changed argument or result counts as progress.',\n 'field.loopText': 'Loop text',\n 'field.loopTextHint': 'Text sent after the loop guard restarts a turn; supports the {tool} placeholder.',\n 'default.loopText': LOCALIZED_TEXT_DEFAULTS.en.loopText,\n 'stats.byCode': 'By error code',\n 'stats.empty': 'No auto-continue activity today.',\n 'stats.reset': 'Reset',\n 'pause.title': 'Paused sessions',\n 'pause.none': 'No sessions paused.',\n 'pause.clearAll': 'Clear all',\n 'pause.unpause': 'Resume',\n 'pause.minutes': 'min',\n 'chrome.collapse': 'Hide settings',\n 'chrome.expand': 'Show settings',\n 'chrome.unsaved': 'Unsaved',\n 'chrome.readOnly': 'This deployment stores settings read-only.',\n 'chrome.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'chrome.discard': 'Discard',\n 'chrome.saving': 'Saving…',\n 'chrome.save': 'Save',\n 'chrome.overridden': 'Overridden',\n 'chrome.reset': 'Reset to default',\n 'chrome.invalidNumber': 'Enter a number, or leave blank to use the default.',\n 'chrome.inherit': 'Inherit',\n 'chrome.on': 'On',\n 'chrome.off': 'Off',\n};\n", "/**\n * The auto-continue settings card: edits the `auto-continue` namespace fields\n * from the plugin-configuration section (the `settings.plugin.item` seat).\n *\n * Self-contained card chrome (disclosure header, staged fields, save/discard\n * footer) following the plugin-card store pattern of the DSH plugin\n * configuration section; styles live in `styles.ts` and use the DSH design\n * tokens so the card follows the active theme.\n */\nimport { useEffect, useState, type ReactNode } from 'react';\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';\nimport { type AutoContinueSettings } from './engine.ts';\nimport { createSnapshotStore, type SettingsScope, type SnapshotStore } from './dsh-store-compat.ts';\nimport {\n pausedSessions,\n readTodayStats,\n resetTodayStats,\n subscribeBridge,\n unpauseSession,\n} from './bridge.ts';\nimport type { SettingsCardKey } from './locales.ts';\nimport {\n booleanField,\n CardForm,\n numberField,\n textField,\n type CardActions,\n type CardFieldState,\n type CardShell,\n} from './settings-form.ts';\nimport { injectStyles } from './styles.ts';\n\n// Styles must land during factory materialization so the module system's\n// style bookkeeping (HMR) owns them.\ninjectStyles();\n\n/** What the auto-continue card renders. */\nexport interface AutoContinueSettingsCardState extends CardShell {\n paused: CardFieldState;\n continueText: CardFieldState;\n continueTextMaxTokens: CardFieldState;\n guardTools: CardFieldState;\n guardPendingText: CardFieldState;\n guardDoneText: CardFieldState;\n graceMs: CardFieldState;\n cooldownMs: CardFieldState;\n maxConsecutive: CardFieldState;\n scanOnBoot: CardFieldState;\n scanLimit: CardFieldState;\n freshMs: CardFieldState;\n verbose: CardFieldState;\n classify: CardFieldState;\n retryableErrorPatterns: CardFieldState;\n backoffFactor: CardFieldState;\n backoffMaxMs: CardFieldState;\n notify: CardFieldState;\n loopGuard: CardFieldState;\n loopShortChars: CardFieldState;\n loopWindowMs: CardFieldState;\n loopShortCount: CardFieldState;\n loopRepeatText: CardFieldState;\n loopToolRepeat: CardFieldState;\n loopText: CardFieldState;\n}\n\n/** The registration-side face the card's slot entry injects. */\nexport interface AutoContinueSettingsCardFace extends CardActions {\n hooks: {\n /** Card snapshot bound by the renderer as useAutoContinueSettingsCard. */\n autoContinueSettingsCard: SnapshotStore<AutoContinueSettingsCardState>;\n };\n}\n\n/** Bridges the `auto-continue` scope onto the card's staged form. */\nexport class AutoContinueSettingsCardController {\n private readonly form: CardForm<AutoContinueSettings>;\n private readonly store: SnapshotStore<AutoContinueSettingsCardState>;\n\n /**\n * @param scope - the bound settings scope for the `auto-continue` namespace.\n */\n constructor(scope: SettingsScope<AutoContinueSettings>) {\n this.form = new CardForm(scope, [\n booleanField('paused'),\n textField('continueText'),\n textField('continueTextMaxTokens'),\n booleanField('guardTools'),\n textField('guardPendingText'),\n textField('guardDoneText'),\n numberField('graceMs', 0),\n numberField('cooldownMs', 0),\n numberField('maxConsecutive', 1),\n booleanField('scanOnBoot'),\n numberField('scanLimit', 1),\n numberField('freshMs', 0),\n booleanField('verbose'),\n booleanField('classify'),\n textField('retryableErrorPatterns'),\n numberField('backoffFactor', 1),\n numberField('backoffMaxMs', 0),\n booleanField('notify'),\n booleanField('loopGuard'),\n numberField('loopShortChars', 1),\n numberField('loopWindowMs', 1000),\n numberField('loopShortCount', 2),\n numberField('loopRepeatText', 2),\n numberField('loopToolRepeat', 2),\n textField('loopText'),\n ]);\n this.store = this.form.bind(() => this.projection(), createSnapshotStore);\n }\n\n private projection(): AutoContinueSettingsCardState {\n return {\n ...this.form.shell(),\n paused: this.form.field('paused'),\n continueText: this.form.field('continueText'),\n continueTextMaxTokens: this.form.field('continueTextMaxTokens'),\n guardTools: this.form.field('guardTools'),\n guardPendingText: this.form.field('guardPendingText'),\n guardDoneText: this.form.field('guardDoneText'),\n graceMs: this.form.field('graceMs'),\n cooldownMs: this.form.field('cooldownMs'),\n maxConsecutive: this.form.field('maxConsecutive'),\n scanOnBoot: this.form.field('scanOnBoot'),\n scanLimit: this.form.field('scanLimit'),\n freshMs: this.form.field('freshMs'),\n verbose: this.form.field('verbose'),\n classify: this.form.field('classify'),\n retryableErrorPatterns: this.form.field('retryableErrorPatterns'),\n backoffFactor: this.form.field('backoffFactor'),\n backoffMaxMs: this.form.field('backoffMaxMs'),\n notify: this.form.field('notify'),\n loopGuard: this.form.field('loopGuard'),\n loopShortChars: this.form.field('loopShortChars'),\n loopWindowMs: this.form.field('loopWindowMs'),\n loopShortCount: this.form.field('loopShortCount'),\n loopRepeatText: this.form.field('loopRepeatText'),\n loopToolRepeat: this.form.field('loopToolRepeat'),\n loopText: this.form.field('loopText'),\n };\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot and its form actions.\n */\n inject(): AutoContinueSettingsCardFace {\n return { hooks: { autoContinueSettingsCard: this.store }, ...this.form.actions() };\n }\n}\n\n/** Props the renderer binds for the auto-continue plugin-configuration card. */\nexport type AutoContinueSettingsCardProps =\n PropsRuntime<'settings.plugin.item'> & PropsLocale<'auto-continue'> & InjectFace<AutoContinueSettingsCardFace>;\n\n/** Card chrome: a disclosure header naming the plugin and what its settings govern, the controls, and the save that writes them. */\nfunction SettingsCard(props: {\n t: (key: SettingsCardKey) => string;\n titleKey: SettingsCardKey;\n descriptionKey: SettingsCardKey;\n state: CardShell;\n onSave: () => void;\n onDiscard: () => void;\n children: ReactNode;\n}) {\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 ? 'dshAcCard dshAcCardOpen' : 'dshAcCard'}>\n <button\n type=\"button\"\n className=\"dshAcHeader\"\n aria-expanded={open}\n aria-label={`${props.t(open ? 'chrome.collapse' : 'chrome.expand')}: ${title}`}\n title={props.t(props.descriptionKey)}\n onClick={() => setOpen(!open)}\n >\n <span className=\"dshAcHeadText\">\n <span className=\"dshAcName\">{title}</span>\n <span className=\"dshAcDescription\">{props.t(props.descriptionKey)}</span>\n </span>\n {state.dirty ? (\n <span className=\"dshAcPending\" title={props.t('chrome.unsaved')}>\n {props.t('chrome.unsaved')}\n </span>\n ) : null}\n <span className={open ? 'dshAcChevron dshAcChevronOpen' : 'dshAcChevron'}>▾</span>\n </button>\n {open ? (\n <div className=\"dshAcBody\">\n {!state.writable ? (\n <p className=\"dshAcReadOnly\" role=\"status\">{props.t('chrome.readOnly')}</p>\n ) : null}\n {props.children}\n <div className=\"dshAcFooter\">\n {state.failed ? (\n <p className=\"dshAcFailed\" role=\"status\">{props.t('chrome.saveFailed')}</p>\n ) : null}\n <button\n type=\"button\"\n className=\"dshAcDiscard\"\n disabled={!state.dirty || state.saving}\n onClick={props.onDiscard}\n >\n {props.t('chrome.discard')}\n </button>\n <button type=\"button\" className=\"dshAcSave\" disabled={blocked} onClick={props.onSave}>\n {props.t(!state.saving ? 'chrome.save' : 'chrome.saving')}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n );\n}\n\n/** Props every field control needs regardless of its value type. */\ninterface FieldProps {\n id: string;\n label: string;\n hint: string;\n text: string;\n overridden: boolean;\n invalid: boolean;\n disabled: boolean;\n t: (key: SettingsCardKey) => string;\n onEdit: (text: string) => void;\n onReset: () => void;\n}\n\n/** A staged value field; `numeric` only hints the keypad, which drafts a field accepts is decided by its spec. */\nfunction ValueField(props: FieldProps & { numeric?: boolean; multiline?: boolean; placeholder?: string }) {\n const className = props.invalid ? 'dshAcInput dshAcInputInvalid' : 'dshAcInput';\n return (\n <div className=\"dshAcField\">\n <div className=\"dshAcHead\">\n <label className=\"dshAcLabel\" htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className=\"dshAcBadges\">\n <span className=\"dshAcBadge\">{props.t('chrome.overridden')}</span>\n <button type=\"button\" className=\"dshAcReset\" disabled={props.disabled} onClick={props.onReset}>\n {props.t('chrome.reset')}\n </button>\n </span>\n ) : null}\n </div>\n {props.multiline === true ? (\n <textarea\n id={props.id}\n className={`${className} dshAcTextArea`}\n aria-invalid={props.invalid || undefined}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n rows={4}\n onChange={(event) => props.onEdit(event.target.value)}\n />\n ) : (\n <input\n id={props.id}\n className={className}\n type=\"text\"\n inputMode={props.numeric === true ? 'numeric' : undefined}\n aria-invalid={props.invalid || undefined}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => props.onEdit(event.target.value)}\n />\n )}\n <p className={props.invalid ? 'dshAcInvalid' : 'dshAcHint'}>\n {props.invalid ? props.t('chrome.invalidNumber') : props.hint}\n </p>\n </div>\n );\n}\n\n/** A staged boolean field: inherit / on / off. */\nfunction BooleanField(props: FieldProps) {\n return (\n <div className=\"dshAcField\">\n <div className=\"dshAcHead\">\n <label className=\"dshAcLabel\" htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className=\"dshAcBadges\">\n <span className=\"dshAcBadge\">{props.t('chrome.overridden')}</span>\n <button type=\"button\" className=\"dshAcReset\" disabled={props.disabled} onClick={props.onReset}>\n {props.t('chrome.reset')}\n </button>\n </span>\n ) : null}\n </div>\n <select\n id={props.id}\n className=\"dshAcSelect\"\n value={props.text}\n disabled={props.disabled}\n onChange={(event) => props.onEdit(event.target.value)}\n >\n <option value=\"\">{props.t('chrome.inherit')}</option>\n <option value=\"true\">{props.t('chrome.on')}</option>\n <option value=\"false\">{props.t('chrome.off')}</option>\n </select>\n <p className=\"dshAcHint\">{props.hint}</p>\n </div>\n );\n}\n\n/** 实时面板: 今日统计 + 已暂停会话。浏览器本地状态, 每 5 秒刷新一次。 */\nfunction LivePanels(props: { t: (key: SettingsCardKey) => string }) {\n const { t } = props;\n const [, refresh] = useState(0);\n useEffect(() => {\n // host 状态桥推送时刷新; 5 秒轮询兜底(桥短暂断线时)\n const unsubscribe = subscribeBridge(() => refresh((value) => value + 1));\n const timer = setInterval(() => refresh((value) => value + 1), 5000);\n return () => {\n unsubscribe();\n clearInterval(timer);\n };\n }, []);\n const stats = readTodayStats();\n const hasStats = stats.sent + stats.skipped + stats.recovered + stats.failed + stats.gaveUp + stats.looped > 0;\n const codes = Object.entries(stats.byCode)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5);\n const paused = pausedSessions();\n return (\n <>\n <section className=\"dshAcPanel\">\n <div className=\"dshAcPanelHead\">\n <span className=\"dshAcPanelTitle\">{t('stats.title')}</span>\n {hasStats ? (\n <button\n type=\"button\"\n className=\"dshAcReset\"\n onClick={() => {\n resetTodayStats();\n refresh((value) => value + 1);\n }}\n >\n {t('stats.reset')}\n </button>\n ) : null}\n </div>\n {!hasStats ? (\n <p className=\"dshAcHint\">{t('stats.empty')}</p>\n ) : (\n <>\n <dl className=\"dshAcStats\">\n <div><dt>{t('stats.sent')}</dt><dd>{stats.sent}</dd></div>\n <div><dt>{t('stats.recovered')}</dt><dd>{stats.recovered}</dd></div>\n <div><dt>{t('stats.failed')}</dt><dd>{stats.failed}</dd></div>\n <div><dt>{t('stats.skipped')}</dt><dd>{stats.skipped}</dd></div>\n <div><dt>{t('stats.gaveUp')}</dt><dd>{stats.gaveUp}</dd></div>\n <div><dt>{t('stats.looped')}</dt><dd>{stats.looped}</dd></div>\n </dl>\n {codes.length > 0 ? (\n <div className=\"dshAcCodes\">\n <span className=\"dshAcHint\">{t('stats.byCode')}:</span>\n {codes.map(([code, count]) => (\n <span key={code} className=\"dshAcCode\">\n {code} ×{count}\n </span>\n ))}\n </div>\n ) : null}\n </>\n )}\n </section>\n <section className=\"dshAcPanel\">\n <div className=\"dshAcPanelHead\">\n <span className=\"dshAcPanelTitle\">{t('pause.title')}</span>\n {paused.length > 0 ? (\n <button\n type=\"button\"\n className=\"dshAcReset\"\n onClick={() => {\n for (const item of paused) unpauseSession(item.sessionId);\n refresh((value) => value + 1);\n }}\n >\n {t('pause.clearAll')}\n </button>\n ) : null}\n </div>\n {paused.length === 0 ? (\n <p className=\"dshAcHint\">{t('pause.none')}</p>\n ) : (\n <ul className=\"dshAcPauseList\">\n {paused.map((item) => (\n <li key={item.sessionId}>\n <span className=\"dshAcPauseId\">{item.sessionId.slice(0, 8)}…</span>\n <span className=\"dshAcHint\">\n {Math.max(1, Math.ceil((item.until - Date.now()) / 60000))} {t('pause.minutes')}\n </span>\n <button\n type=\"button\"\n className=\"dshAcReset\"\n onClick={() => {\n unpauseSession(item.sessionId);\n refresh((value) => value + 1);\n }}\n >\n {t('pause.unpause')}\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </>\n );\n}\n\n/**\n * Render the auto-continue card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function AutoContinueSettingsCard(props: AutoContinueSettingsCardProps) {\n const { t } = props;\n const state = props.useAutoContinueSettingsCard((snapshot) => snapshot);\n const disabled = !state.writable;\n const shared = { t, disabled };\n return (\n <SettingsCard\n t={t}\n titleKey=\"card.title\"\n descriptionKey=\"card.description\"\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <BooleanField\n id=\"auto-continue-paused\"\n label={t('field.paused')}\n hint={t('field.pausedHint')}\n {...shared}\n {...state.paused}\n onEdit={(text) => props.edit('paused', text)}\n onReset={() => props.resetField('paused')}\n />\n <ValueField\n id=\"auto-continue-continue-text\"\n label={t('field.continueText')}\n hint={t('field.continueTextHint')}\n {...shared}\n {...state.continueText}\n onEdit={(text) => props.edit('continueText', text)}\n placeholder={t('default.continueText')}\n onReset={() => props.resetField('continueText')}\n />\n <ValueField\n id=\"auto-continue-continue-text-max-tokens\"\n label={t('field.continueTextMaxTokens')}\n hint={t('field.continueTextMaxTokensHint')}\n {...shared}\n {...state.continueTextMaxTokens}\n onEdit={(text) => props.edit('continueTextMaxTokens', text)}\n placeholder={t('default.continueTextMaxTokens')}\n onReset={() => props.resetField('continueTextMaxTokens')}\n />\n <BooleanField\n id=\"auto-continue-guard-tools\"\n label={t('field.guardTools')}\n hint={t('field.guardToolsHint')}\n {...shared}\n {...state.guardTools}\n onEdit={(text) => props.edit('guardTools', text)}\n onReset={() => props.resetField('guardTools')}\n />\n <ValueField\n id=\"auto-continue-guard-pending-text\"\n label={t('field.guardPendingText')}\n hint={t('field.guardPendingTextHint')}\n {...shared}\n {...state.guardPendingText}\n onEdit={(text) => props.edit('guardPendingText', text)}\n placeholder={t('default.guardPendingText')}\n onReset={() => props.resetField('guardPendingText')}\n />\n <ValueField\n id=\"auto-continue-guard-done-text\"\n label={t('field.guardDoneText')}\n hint={t('field.guardDoneTextHint')}\n {...shared}\n {...state.guardDoneText}\n onEdit={(text) => props.edit('guardDoneText', text)}\n placeholder={t('default.guardDoneText')}\n onReset={() => props.resetField('guardDoneText')}\n />\n <ValueField\n id=\"auto-continue-grace-ms\"\n label={t('field.graceMs')}\n hint={t('field.graceMsHint')}\n numeric\n {...shared}\n {...state.graceMs}\n onEdit={(text) => props.edit('graceMs', text)}\n onReset={() => props.resetField('graceMs')}\n />\n <ValueField\n id=\"auto-continue-cooldown-ms\"\n label={t('field.cooldownMs')}\n hint={t('field.cooldownMsHint')}\n numeric\n {...shared}\n {...state.cooldownMs}\n onEdit={(text) => props.edit('cooldownMs', text)}\n onReset={() => props.resetField('cooldownMs')}\n />\n <ValueField\n id=\"auto-continue-max-consecutive\"\n label={t('field.maxConsecutive')}\n hint={t('field.maxConsecutiveHint')}\n numeric\n {...shared}\n {...state.maxConsecutive}\n onEdit={(text) => props.edit('maxConsecutive', text)}\n onReset={() => props.resetField('maxConsecutive')}\n />\n <BooleanField\n id=\"auto-continue-scan-on-boot\"\n label={t('field.scanOnBoot')}\n hint={t('field.scanOnBootHint')}\n {...shared}\n {...state.scanOnBoot}\n onEdit={(text) => props.edit('scanOnBoot', text)}\n onReset={() => props.resetField('scanOnBoot')}\n />\n <ValueField\n id=\"auto-continue-scan-limit\"\n label={t('field.scanLimit')}\n hint={t('field.scanLimitHint')}\n numeric\n {...shared}\n {...state.scanLimit}\n onEdit={(text) => props.edit('scanLimit', text)}\n onReset={() => props.resetField('scanLimit')}\n />\n <ValueField\n id=\"auto-continue-fresh-ms\"\n label={t('field.freshMs')}\n hint={t('field.freshMsHint')}\n numeric\n {...shared}\n {...state.freshMs}\n onEdit={(text) => props.edit('freshMs', text)}\n onReset={() => props.resetField('freshMs')}\n />\n <BooleanField\n id=\"auto-continue-verbose\"\n label={t('field.verbose')}\n hint={t('field.verboseHint')}\n {...shared}\n {...state.verbose}\n onEdit={(text) => props.edit('verbose', text)}\n onReset={() => props.resetField('verbose')}\n />\n <BooleanField\n id=\"auto-continue-classify\"\n label={t('field.classify')}\n hint={t('field.classifyHint')}\n {...shared}\n {...state.classify}\n onEdit={(text) => props.edit('classify', text)}\n onReset={() => props.resetField('classify')}\n />\n <ValueField\n id=\"auto-continue-retryable-error-patterns\"\n label={t('field.retryableErrorPatterns')}\n hint={t('field.retryableErrorPatternsHint')}\n multiline\n {...shared}\n {...state.retryableErrorPatterns}\n onEdit={(text) => props.edit('retryableErrorPatterns', text)}\n placeholder=\"Upstream rejected the request as invalid\"\n onReset={() => props.resetField('retryableErrorPatterns')}\n />\n <ValueField\n id=\"auto-continue-backoff-factor\"\n label={t('field.backoffFactor')}\n hint={t('field.backoffFactorHint')}\n numeric\n {...shared}\n {...state.backoffFactor}\n onEdit={(text) => props.edit('backoffFactor', text)}\n onReset={() => props.resetField('backoffFactor')}\n />\n <ValueField\n id=\"auto-continue-backoff-max\"\n label={t('field.backoffMaxMs')}\n hint={t('field.backoffMaxMsHint')}\n numeric\n {...shared}\n {...state.backoffMaxMs}\n onEdit={(text) => props.edit('backoffMaxMs', text)}\n onReset={() => props.resetField('backoffMaxMs')}\n />\n <BooleanField\n id=\"auto-continue-notify\"\n label={t('field.notify')}\n hint={t('field.notifyHint')}\n {...shared}\n {...state.notify}\n onEdit={(text) => props.edit('notify', text)}\n onReset={() => props.resetField('notify')}\n />\n <BooleanField\n id=\"auto-continue-loop-guard\"\n label={t('field.loopGuard')}\n hint={t('field.loopGuardHint')}\n {...shared}\n {...state.loopGuard}\n onEdit={(text) => props.edit('loopGuard', text)}\n onReset={() => props.resetField('loopGuard')}\n />\n <ValueField\n id=\"auto-continue-loop-short-chars\"\n label={t('field.loopShortChars')}\n hint={t('field.loopShortCharsHint')}\n numeric\n {...shared}\n {...state.loopShortChars}\n onEdit={(text) => props.edit('loopShortChars', text)}\n onReset={() => props.resetField('loopShortChars')}\n />\n <ValueField\n id=\"auto-continue-loop-window-ms\"\n label={t('field.loopWindowMs')}\n hint={t('field.loopWindowMsHint')}\n numeric\n {...shared}\n {...state.loopWindowMs}\n onEdit={(text) => props.edit('loopWindowMs', text)}\n onReset={() => props.resetField('loopWindowMs')}\n />\n <ValueField\n id=\"auto-continue-loop-short-count\"\n label={t('field.loopShortCount')}\n hint={t('field.loopShortCountHint')}\n numeric\n {...shared}\n {...state.loopShortCount}\n onEdit={(text) => props.edit('loopShortCount', text)}\n onReset={() => props.resetField('loopShortCount')}\n />\n <ValueField\n id=\"auto-continue-loop-tool-repeat\"\n label={t('field.loopToolRepeat')}\n hint={t('field.loopToolRepeatHint')}\n numeric\n {...shared}\n {...state.loopToolRepeat}\n onEdit={(text) => props.edit('loopToolRepeat', text)}\n onReset={() => props.resetField('loopToolRepeat')}\n />\n <ValueField\n id=\"auto-continue-loop-repeat-text\"\n label={t('field.loopRepeatText')}\n hint={t('field.loopRepeatTextHint')}\n numeric\n {...shared}\n {...state.loopRepeatText}\n onEdit={(text) => props.edit('loopRepeatText', text)}\n onReset={() => props.resetField('loopRepeatText')}\n />\n <ValueField\n id=\"auto-continue-loop-text\"\n label={t('field.loopText')}\n hint={t('field.loopTextHint')}\n {...shared}\n {...state.loopText}\n onEdit={(text) => props.edit('loopText', text)}\n placeholder={t('default.loopText')}\n onReset={() => props.resetField('loopText')}\n />\n <LivePanels t={t} />\n </SettingsCard>\n );\n}\n", "/**\n * Snapshot-store bridge across the two public DSH client module layouts.\n *\n * DSH 0.1.2 moved the store engine from the dynamic\n * `@deepseek-ai/dsh-client-runtime/client` row into the shell-seeded\n * `@deepseek-ai/dsh-client-store` platform module. Keep the probe dynamic so\n * esbuild does not turn both candidates into eager top-level requires: the\n * loader must only resolve the module that exists in the running DSH cohort.\n */\n\n/** Writable observable snapshot used by the settings card. */\nexport interface SnapshotStore<T> {\n getSnapshot(): T;\n subscribe(listener: () => void): () => void;\n update(mutator: (draft: T) => void): void;\n set(next: T): void;\n}\n\n/** Settings state consumed by the staged form. */\nexport interface SettingsScopeSnapshot<T> {\n status: 'loading' | 'ready' | 'unavailable';\n value: T | undefined;\n base: unknown;\n user: unknown;\n revision: number | undefined;\n writable: boolean;\n mode: 'host' | 'memory';\n}\n\n/** Stable subset shared by the legacy and DSH 0.1.2 settings scopes. */\nexport interface SettingsScope<T> {\n getSnapshot(): SettingsScopeSnapshot<T>;\n subscribe(listener: () => void): () => void;\n set(field: string, value: unknown): Promise<void>;\n unset(field: string): Promise<void>;\n}\n\ninterface SnapshotStoreModule {\n createSnapshotStore<T>(\n init: T,\n options?: { flush?: 'raf' | 'sync'; persist?: { name: string } },\n ): SnapshotStore<T>;\n}\n\nfunction resolveSnapshotStore(): SnapshotStoreModule {\n // String assembly is intentional: it preserves the lazy try/fallback in the\n // emitted client bundle instead of letting the bundler resolve both names.\n const current = ['@deepseek-ai/dsh-client', '-store'].join('');\n const legacy = ['@deepseek-ai/dsh-client-runtime', '/client'].join('');\n try {\n return require(current) as SnapshotStoreModule;\n } catch {\n return require(legacy) as SnapshotStoreModule;\n }\n}\n\nexport const { createSnapshotStore } = resolveSnapshotStore();\n", "/**\n * Host status bridge, browser side.\n *\n * Subscribes to the host engine's `/api/auto-continue-bridge` SSE stream:\n * notifications (shown via the browser Notification API, action buttons POST\n * to `/api/auto-continue-action`) and runtime state (today's stats and the\n * paused-sessions list) consumed by the settings card's live panels.\n */\n\n/** 今日统计视图(与 host 引擎的 DayStats 对应)。 */\nexport interface DayStatsView {\n date: string;\n sent: number;\n skipped: number;\n recovered: number;\n failed: number;\n gaveUp: number;\n looped: number;\n byCode: Record<string, number>;\n}\n\n/** 已暂停会话视图。 */\nexport interface PausedSessionView {\n sessionId: string;\n until: number;\n}\n\ninterface BridgeState {\n stats: DayStatsView;\n paused: PausedSessionView[];\n}\n\ninterface BridgeNotice {\n id: string;\n title: string;\n body: string;\n sessionId?: string;\n actions: { action: string; title: string }[];\n at: number;\n}\n\nconst EMPTY_STATS: DayStatsView = {\n date: '',\n sent: 0,\n skipped: 0,\n recovered: 0,\n failed: 0,\n gaveUp: 0,\n looped: 0,\n byCode: {},\n};\n\nlet state: BridgeState = { stats: EMPTY_STATS, paused: [] };\nconst listeners = new Set<() => void>();\n\n/** 当前桥状态里的已暂停会话(卡片面板用)。 */\nexport function pausedSessions(): PausedSessionView[] {\n return state.paused;\n}\n\n/** 当前桥状态里的今日统计(卡片面板用)。 */\nexport function readTodayStats(): DayStatsView {\n return state.stats;\n}\n\n/** 清零今日统计(经动作端点交给 host 引擎执行)。 */\nexport function resetTodayStats(): void {\n void postAction({ action: 'reset-stats' });\n}\n\n/** 解除某个会话的暂停(经动作端点交给 host 引擎执行)。 */\nexport function unpauseSession(sessionId: string): void {\n void postAction({ action: 'unpause', sessionId });\n}\n\n/** 订阅桥状态变化(卡片面板刷新用)。 */\nexport function subscribeBridge(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/** 通知按钮动作回传 host(立即续跑 / 暂停该会话 1 小时 / 解除暂停 / 清零统计)。 */\nasync function postAction(payload: { action: string; sessionId?: string }): Promise<void> {\n try {\n await fetch('/api/auto-continue-action', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n });\n } catch {\n /* host 不可达时静默 */\n }\n}\n\nfunction handleEvent(event: { type: string; notice?: BridgeNotice; stats?: DayStatsView; paused?: PausedSessionView[] }): void {\n if (event.type === 'state') {\n state = {\n stats: event.stats ?? EMPTY_STATS,\n paused: event.paused ?? [],\n };\n for (const listener of listeners) listener();\n } else if (event.type === 'notice' && event.notice !== undefined) {\n showNotification(event.notice);\n }\n}\n\n/** 浏览器通知: 展示 host 通知并挂动作按钮。 */\nfunction showNotification(notice: BridgeNotice): void {\n try {\n const N = (globalThis as { Notification?: unknown }).Notification as\n | (new (t: string, o: { body: string; actions?: { action: string; title: string }[] }) => unknown)\n | undefined;\n if (typeof N === 'undefined') return;\n const permission = (N as unknown as { permission?: string }).permission;\n const create = (): void => {\n const instance = new N(notice.title, {\n body: notice.body,\n ...(notice.actions.length > 0 ? { actions: notice.actions } : {}),\n });\n const target = instance as {\n onclick?: (() => void) | null;\n onaction?: ((event: { action: string }) => void) | null;\n };\n target.onclick = () => {\n try {\n (globalThis as { focus?: () => void }).focus?.();\n } catch {\n /* ignore */\n }\n };\n target.onaction = (event) => {\n if (notice.sessionId !== undefined) {\n void postAction({ action: event.action, sessionId: notice.sessionId });\n }\n };\n };\n if (permission === 'granted') {\n create();\n } else if (permission === 'default') {\n void (N as unknown as { requestPermission?: () => Promise<string> }).requestPermission?.()\n .then((result) => {\n if (result === 'granted') create();\n })\n .catch(() => {});\n }\n } catch {\n /* 通知失败不影响核心逻辑 */\n }\n}\n\n/**\n * 启动桥订阅(带断线重连), 返回停止函数。\n * 由 client apply 的 ctx.effect 持有。\n */\nexport function startBridge(): () => void {\n let stopped = false;\n let controller: AbortController | undefined;\n\n const loop = async (): Promise<void> => {\n while (!stopped) {\n controller = new AbortController();\n try {\n const response = await fetch('/api/auto-continue-bridge', { signal: controller.signal });\n if (!response.ok || response.body === null) throw new Error(`bridge HTTP ${response.status}`);\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let idx = buffer.indexOf('\\n\\n');\n while (idx !== -1) {\n const chunk = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n for (const line of chunk.split('\\n')) {\n if (line.startsWith('data: ')) {\n try {\n handleEvent(JSON.parse(line.slice(6)) as Parameters<typeof handleEvent>[0]);\n } catch {\n /* 忽略坏帧 */\n }\n }\n }\n idx = buffer.indexOf('\\n\\n');\n }\n }\n } catch {\n /* 断线: 退避重连 */\n }\n if (!stopped) await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n };\n void loop();\n\n return () => {\n stopped = true;\n controller?.abort();\n };\n}\n", "/**\n * Staged form model behind the plugin settings card — a self-contained\n * implementation of the plugin-card store pattern used by the DSH plugin\n * configuration section.\n *\n * A card stages what the user types and writes it only when they save. Each\n * settings write is a durable, revision-fenced document mutation, so staging\n * keeps what is on screen exactly what a save would store. A field shows its\n * effective value — the user layer over the composition layer over the schema\n * default — and whether the user layer carries it (presence, not value\n * equality, marks an override).\n */\nimport type { SettingsScope, SnapshotStore } from './dsh-store-compat.ts';\n\n/** The write one field's staged text performs when the card is saved. */\nexport type FieldWrite = { kind: 'set'; value: unknown } | { kind: 'clear' };\n\n/** How one field converts between its stored value and its draft text. */\nexport interface CardFieldSpec {\n /** Field name inside the namespace section. */\n field: string;\n /** Render a stored value as draft text; the empty string when the section carries none. */\n format: (value: unknown) => string;\n /**\n * The write this draft text stages, or undefined when the text is not a\n * value this field accepts — which blocks the save rather than discarding it.\n */\n parse: (text: string) => FieldWrite | undefined;\n}\n\n/** One field as the card's control renders it. */\nexport interface CardFieldState {\n /** Draft text the control renders. */\n text: string;\n /** Whether saving would leave a user-layer entry for this field. */\n overridden: boolean;\n /** Whether the draft is not a value this field accepts, which blocks saving. */\n invalid: boolean;\n}\n\n/** Form state every plugin card shares. */\nexport interface CardShell {\n /** False while the namespace is not served to this client; the card renders nothing. */\n available: boolean;\n /** Whether the Host document accepts writes. */\n writable: boolean;\n /** Whether the form holds edits that a save would write. */\n dirty: boolean;\n /** Whether any staged draft is invalid, which blocks the save. */\n invalid: boolean;\n /** Whether a save is crossing the wire. */\n saving: boolean;\n /** Whether the last save did not land as staged; cleared by the next edit or save. */\n failed: boolean;\n}\n\n/** The write actions the 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 saving lets the field re-inherit 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\n/** A whole-number field. An empty draft clears the field; a non-number or out-of-range draft blocks the save. */\nexport function numberField(field: string, min = 0): 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 if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < min) return undefined;\n return { kind: 'set', value: parsed };\n },\n };\n}\n\n/** A free-text field. An empty draft clears the field, so emptying the control and saving is the same gesture as resetting it. */\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/** A boolean field, edited through true/false draft text; an empty draft inherits. */\nexport function booleanField(field: string): CardFieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim();\n if (trimmed === '') return { kind: 'clear' };\n if (trimmed === 'true') return { kind: 'set', value: true };\n if (trimmed === 'false') return { kind: 'set', value: false };\n return undefined;\n },\n };\n}\n\n/** One field's staged edit. */\ninterface StagedEdit {\n /** Draft text the control renders. */\n text: string;\n /** True when this edit clears the field whatever text it shows. */\n clear: boolean;\n}\n\n/**\n * Stages one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted, so the\n * outcome is read back from the section rather than predicted here. A save\n * that did not land keeps its drafts, so the user can correct them instead of\n * retyping.\n */\nexport class CardForm<T> {\n private readonly specs: Map<string, CardFieldSpec>;\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 - the bound settings scope for this card's namespace.\n * @param specs - the section fields this card edits.\n */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: CardFieldSpec[],\n ) {\n this.specs = new Map(specs.map((spec) => [spec.field, spec]));\n this.scope.subscribe(() => this.publish());\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S, createStore: (init: S) => SnapshotStore<S>): SnapshotStore<S> {\n const store = createStore(project());\n this.listeners.add(() => store.set(project()));\n return store;\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot();\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: this.plan().length > 0,\n invalid: this.plan().some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n };\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): CardFieldState {\n const spec = this.specOf(field);\n const staged = this.staged.get(field);\n if (staged === undefined) {\n return {\n text: spec.format(this.sectionValue(field)),\n overridden: this.stored(field),\n invalid: false,\n };\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 /** The actions the card's slot registration injects. */\n actions(): CardActions {\n return {\n edit: (field, text) => this.stage(field, { text, clear: false }),\n resetField: (field) => {\n this.stage(field, { text: this.specOf(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 /**\n * Write every staged edit, then re-seed from what the Host accepted.\n * @returns settlement after every write and the read-back.\n */\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 // Snapshot the fields this save writes, so edits staged while it is in\n // flight survive: only the staged keys this save actually wrote are cleared.\n const fields = new Set(plan.map((item) => item.field));\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) {\n for (const field of fields) this.staged.delete(field);\n }\n this.saving = false;\n this.failed = !landed;\n this.publish();\n }\n\n /**\n * Every staged edit a save would write. An entry whose draft is not a value\n * its field accepts carries no write: the form is still dirty, and the save\n * refuses rather than dropping the edit. A staged edit that matches the\n * effective section is not a write at all.\n */\n private plan(): { field: string; run: (() => Promise<boolean>) | undefined }[] {\n const plan: { field: string; run: (() => Promise<boolean>) | undefined }[] = [];\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(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 }\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 specOf(field: string): CardFieldSpec {\n const spec = this.specs.get(field);\n if (spec === undefined) throw new Error(`settings card has no field ${field}`);\n return spec;\n }\n\n private sectionValue(field: string): unknown {\n return (this.scope.getSnapshot().value as Record<string, unknown> | undefined)?.[field];\n }\n\n private baseValue(field: string): unknown {\n return (this.scope.getSnapshot().base as Record<string, unknown> | undefined)?.[field];\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.scope.getSnapshot().user as Record<string, unknown> | undefined;\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer();\n return user !== undefined && Object.prototype.hasOwnProperty.call(user, field);\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener();\n }\n}\n", "/**\n * Styles for the auto-continue settings card, injected at factory\n * materialization so the client module system's style bookkeeping (HMR) owns\n * them. Uses the DSH design tokens (`--dsw-alias-*`) so the card follows the\n * active theme.\n */\n\nconst css = `\n.dshAcCard {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n border-radius: 12px;\n list-style: none;\n transition: border-color .16s, background .16s;\n}\n.dshAcCard:hover { border-color: var(--dsw-alias-label-dimmed); }\n.dshAcCardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: var(--dsw-alias-label-dimmed);\n}\n.dshAcHeader {\n appearance: none;\n width: 100%;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: none;\n border: 0;\n border-radius: 12px;\n align-items: center;\n gap: 12px;\n padding: 14px 16px;\n display: flex;\n}\n.dshAcHeader:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: -2px; }\n.dshAcHeadText { flex-direction: column; flex: 1; gap: 4px; min-width: 0; display: flex; }\n.dshAcName { color: var(--dsw-alias-label-primary); font-size: 15px; font-weight: 600; line-height: 1.4; }\n.dshAcDescription { color: var(--dsw-alias-label-tertiary); font-size: 13px; line-height: 1.5; }\n.dshAcChevron { color: var(--dsw-alias-label-tertiary); flex: none; transition: transform .16s; }\n.dshAcChevronOpen { transform: rotate(180deg); }\n.dshAcBody { border-top: 1px solid var(--dsw-alias-border-l2); margin: 0 16px; padding-bottom: 8px; }\n.dshAcReadOnly { color: var(--dsw-alias-label-tertiary); margin: 12px 0 0; font-size: 12px; line-height: 1.5; }\n.dshAcPending {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n flex: none;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcFooter {\n border-top: 1px solid var(--dsw-alias-border-l2);\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 12px 0 4px;\n display: flex;\n}\n.dshAcFailed { min-width: 0; color: var(--dsw-alias-label-error); flex: 1; margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcDiscard, .dshAcSave {\n appearance: none;\n font: inherit;\n cursor: pointer;\n border: 1px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcDiscard { border-color: var(--dsw-alias-border-l2); color: var(--dsw-alias-label-secondary); background: none; }\n.dshAcDiscard:hover:not(:disabled) { color: var(--dsw-alias-label-primary); border-color: var(--dsw-alias-label-dimmed); }\n.dshAcSave { background: var(--dsw-alias-label-primary); color: var(--dsw-alias-bg-layer-3); }\n.dshAcDiscard:disabled, .dshAcSave:disabled { opacity: .4; cursor: default; }\n.dshAcDiscard:focus-visible, .dshAcSave:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 1px; }\n.dshAcField { flex-direction: column; gap: 6px; padding: 12px 0; display: flex; }\n.dshAcField + .dshAcField { border-top: 1px solid var(--dsw-alias-border-l2); }\n.dshAcHead { align-items: center; gap: 8px; display: flex; }\n.dshAcLabel { min-width: 0; color: var(--dsw-alias-label-primary); flex: 1; font-size: 13px; font-weight: 500; line-height: 1.5; }\n.dshAcBadges { align-items: center; gap: 8px; display: inline-flex; }\n.dshAcBadge {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcReset {\n font: inherit;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n background: none;\n border: none;\n padding: 0;\n font-size: 12px;\n line-height: 1.5;\n}\n.dshAcReset:hover:not(:disabled) { color: var(--dsw-alias-label-primary); }\n.dshAcReset:disabled { cursor: default; }\n.dshAcInput {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n height: 34px;\n font: inherit;\n color: var(--dsw-alias-label-primary);\n border-radius: 8px;\n padding: 0 12px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcInput:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }\n.dshAcInput:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.dshAcInputInvalid { border-color: var(--dsw-alias-label-error); }\n.dshAcTextArea { box-sizing: border-box; height: auto; min-height: 84px; padding: 8px 12px; resize: vertical; }\n.dshAcSelect {\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n height: 34px;\n font: inherit;\n color: var(--dsw-alias-label-primary);\n border-radius: 8px;\n padding: 0 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcSelect:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }\n.dshAcSelect:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.dshAcInvalid { color: var(--dsw-alias-label-error); margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcHint { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcPanel { border-top: 1px solid var(--dsw-alias-border-l2); flex-direction: column; gap: 8px; padding: 12px 0; display: flex; }\n.dshAcPanelHead { align-items: center; gap: 8px; display: flex; }\n.dshAcPanelTitle { color: var(--dsw-alias-label-primary); flex: 1; font-size: 13px; font-weight: 600; line-height: 1.5; }\n.dshAcStats { gap: 4px 16px; margin: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); display: grid; }\n.dshAcStats > div { justify-content: space-between; gap: 8px; display: flex; }\n.dshAcStats dt { color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 1.5; }\n.dshAcStats dd { color: var(--dsw-alias-label-primary); margin: 0; font-size: 12px; font-weight: 600; line-height: 1.5; }\n.dshAcCodes { flex-wrap: wrap; align-items: center; gap: 6px; display: flex; }\n.dshAcCode {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcPauseList { flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; display: flex; }\n.dshAcPauseList li { align-items: center; gap: 8px; display: flex; }\n.dshAcPauseId {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 1.5;\n}\n`;\n\n/** Inject the stylesheet once; a no-op outside a browser environment. */\nexport function injectStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.querySelector('style[data-plugin-css=\"auto-continue/card\"]') !== null) return;\n const tag = document.createElement('style');\n tag.dataset.plugin = 'dsh-client-auto-continue';\n tag.dataset.pluginCss = 'auto-continue/card';\n tag.textContent = css;\n document.head.appendChild(tag);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Auto-continue plugin, browser half (thin shell).\n *\n * Since 0.8.0 the auto-continue ENGINE runs inside the host process (single\n * instance — see src/host/engine.ts), so this half only:\n * - registers the `auto-continue` settings card (`settings.plugin.item`),\n * - subscribes to the host status bridge (SSE) and shows browser\n * notifications with action buttons (Resume now / Pause 1h) via the bridge\n * action endpoint,\n * - feeds the card's stats / paused-sessions panels from the bridge state.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis';\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client';\n// Type-only: pulls the settings-surface SlotMap merge and ctx.settingsScope.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client';\n// Type-only: pulls the `settings.plugin.item` SlotMap merge.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client';\nimport { type AutoContinueSettings } from './engine.ts';\nimport { en, zh, type SettingsCardKey } from './locales.ts';\nimport {\n AutoContinueSettingsCard,\n AutoContinueSettingsCardController,\n} from './settings-card.tsx';\nimport { startBridge } from './bridge.ts';\n\n/** Dictionary namespace owned by this plugin. */\nconst NS = 'auto-continue';\n\n/** Settings namespace the settings card edits (the host engine reads it). */\nconst SETTINGS_NS = 'auto-continue';\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** auto-continue settings-card copy. */\n 'auto-continue': SettingsCardKey;\n }\n}\n\n/** Services required by this plugin. */\nexport const inject = ['slots', 'locale', 'settingsScope'];\n\n// 浏览器侧辅助(设置卡片用): 桥状态读取与暂停解除。\nexport {\n pausedSessions,\n readTodayStats,\n resetTodayStats,\n unpauseSession,\n} from './bridge.ts';\n\n/**\n * Plugin body: settings card + host status bridge (notifications, stats,\n * paused sessions).\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'auto-continue: dictionaries');\n\n const scope = ctx.settingsScope.bind<AutoContinueSettings>({ namespace: SETTINGS_NS });\n const syncLocale = (): void => {\n const active = ctx.locale.getLocale().active;\n const snapshot = scope.getSnapshot();\n if (snapshot.status !== 'ready' || !snapshot.writable || snapshot.mode !== 'host') return;\n if (snapshot.value?.locale === active) return;\n void scope.set('locale', active);\n };\n ctx.effect(() => scope.subscribe(syncLocale), 'auto-continue: locale settings sync');\n ctx.on('locale/change', syncLocale);\n syncLocale();\n\n // 状态桥: 订阅 host 的通知与运行时状态, 弹浏览器通知并驱动卡片面板。\n ctx.effect(() => startBridge(), 'auto-continue: host bridge');\n\n // Plugin configuration card: one staged form over the `auto-continue`\n // settings namespace, contributed to the plugin-configuration section\n // (Settings → Plugins). Since DSH 0.1.0-rc.7 `settings.plugin.item` is a\n // keyed slot dispatched by the settings namespace it edits, so the entry\n // registers with `key` (the namespace), like the official cards.\n const controller = new AutoContinueSettingsCardController(scope);\n ctx.slots.inject('settings.plugin.item', () =>\n ctx.slots.register(\n {\n name: 'settings.plugin.item',\n key: SETTINGS_NS,\n locale: NS,\n inject: () => controller.inject(),\n },\n AutoContinueSettingsCard,\n ),\n );\n}\n", "/** 共享核心: 平台无关的纯逻辑与类型。\n *\n * 被 host 引擎(src/host/engine.ts)与浏览器半侧共用: 配置解析、错误分类、\n * 模板填充、自适应退避、幂等护栏的工具结果提取、循环守卫的会话状态机,\n * 以及回显识别。引擎迁入 host 后(0.8.0), 浏览器半侧只 re-export 本模块。\n */\nimport type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session/types';\n\n/** Supported UI/config locales. Any unknown browser locale falls back to Chinese. */\nexport type AutoContinueLocale = 'en' | 'zh';\n\n/** Locale-owned defaults for the user-editable text fields. */\nexport const LOCALIZED_TEXT_DEFAULTS = {\n zh: {\n continueText: '继续',\n continueTextMaxTokens: '继续',\n guardPendingText: '(上一步工具「{tool}」可能未完成, 先确认状态再继续, 不要重复执行)',\n guardDoneText: '(上一步工具「{tool}」已完成, 结果: {result}; 不要重复执行, 直接继续)',\n loopText: '(检测到你可能陷入循环, 请停止重复刚才的动作, 换一种方式继续)',\n },\n en: {\n continueText: 'Continue',\n continueTextMaxTokens: 'Continue',\n guardPendingText:\n '(The previous tool \"{tool}\" may not have completed. Check its state before continuing and do not run it again.)',\n guardDoneText:\n '(The previous tool \"{tool}\" completed successfully. Result: {result}; do not run it again. Continue from there.)',\n loopText:\n '(You may be stuck in a loop. Stop repeating the last action and continue with a different approach.)',\n },\n} as const satisfies Record<AutoContinueLocale, Record<string, string>>;\n\n/** The `auto-continue` settings section (all fields optional on the wire; the host schema carries defaults). */\nexport interface AutoContinueSettings {\n /** Active browser/UI locale mirrored by the client. */\n locale?: AutoContinueLocale;\n /** Text automatically sent after an interruption. */\n continueText?: string;\n /** Text sent when the output token ceiling is reached (same placeholders as `continueText`). */\n continueTextMaxTokens?: string;\n /** Idempotency guard: inspect the last tool call before resuming and steer the model. */\n guardTools?: boolean;\n /** Guard text appended when the last tool call has no confirmed result (it may have partially executed). */\n guardPendingText?: string;\n /** Guard text appended when the last tool call completed successfully (don't rerun it). */\n guardDoneText?: string;\n /** Grace period after an interruption before auto-sending (ms). */\n graceMs?: number;\n /** Minimum interval between two auto-continues per session (ms). */\n cooldownMs?: number;\n /** Max consecutive auto-continues per session before stopping. */\n maxConsecutive?: number;\n /** Scan recently interrupted sessions on page load / reconnect. */\n scanOnBoot?: boolean;\n /** Max sessions the scan checks (most recently updated). */\n scanLimit?: number;\n /** Scan only considers interruptions inside this window (ms). */\n freshMs?: number;\n /** Log `[auto-continue]` lines to the browser console. */\n verbose?: boolean;\n /** Classify failures: auto-continue transient errors only; permanent ones (auth/balance/model) are skipped and notified. */\n classify?: boolean;\n /** Provider-specific message/code/status fragments that explicitly count as retryable, one literal per line. */\n retryableErrorPatterns?: string;\n /** Cooldown multiplier per consecutive failure (adaptive backoff). */\n backoffFactor?: number;\n /** Cap on the effective backoff interval (ms). */\n backoffMaxMs?: number;\n /** Show browser notifications for auto-continue events. */\n notify?: boolean;\n /** Globally pause auto-continue: no live or scan send, queued pending sends cancelled. */\n paused?: boolean;\n /** Loop guard: detect a running turn spinning in place (short talk without tools, or the same tool repeating) and restart it. */\n loopGuard?: boolean;\n /** A model message shorter than this many chars counts as a \"short sentence\" (loop signal). */\n loopShortChars?: number;\n /** Consecutive short sentences within this window (ms) with no tool call in between trip the loop guard. */\n loopWindowMs?: number;\n /** Consecutive short sentences trip the loop guard. */\n loopShortCount?: number;\n /** Consecutive identical tool calls with identical arguments AND identical results trip the loop guard. */\n loopToolRepeat?: number;\n /** Consecutive identical short sentences trip the loop guard (strongest spinning signal). */\n loopRepeatText?: number;\n /** Text sent after the loop guard cancels and restarts a turn (supports {tool}). */\n loopText?: string;\n}\n\n/** Fully resolved configuration (built-in defaults + user overrides). */\nexport type AutoContinueConfig = Required<AutoContinueSettings>;\n\n/** Effective built-in defaults; localized text fields use Chinese until a browser locale is mirrored. */\nexport const DEFAULT_CONFIG: AutoContinueConfig = {\n locale: 'zh',\n ...LOCALIZED_TEXT_DEFAULTS.zh,\n guardTools: true,\n graceMs: 3000,\n cooldownMs: 20000,\n maxConsecutive: 3,\n scanOnBoot: true,\n scanLimit: 8,\n freshMs: 15 * 60 * 1000,\n verbose: true,\n classify: true,\n retryableErrorPatterns: '',\n backoffFactor: 2,\n backoffMaxMs: 300000,\n notify: false,\n paused: false,\n loopGuard: true,\n loopShortChars: 40,\n loopWindowMs: 30000,\n loopShortCount: 12,\n loopRepeatText: 4,\n loopToolRepeat: 5,\n};\n\nfunction numberOr(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : fallback;\n}\n\nfunction booleanOr(value: unknown, fallback: boolean): boolean {\n return typeof value === 'boolean' ? value : fallback;\n}\n\n/** Resolve a (possibly partial / not-yet-loaded) settings section to a full config. */\nexport function resolveConfig(section: AutoContinueSettings | undefined): AutoContinueConfig {\n const value = section ?? {};\n const locale: AutoContinueLocale = value.locale === 'en' ? 'en' : 'zh';\n const localized = LOCALIZED_TEXT_DEFAULTS[locale];\n const text =\n typeof value.continueText === 'string' && value.continueText.trim() !== ''\n ? value.continueText\n : localized.continueText;\n const maxTokensText =\n typeof value.continueTextMaxTokens === 'string' && value.continueTextMaxTokens.trim() !== ''\n ? value.continueTextMaxTokens\n : localized.continueTextMaxTokens;\n const guardPendingText =\n typeof value.guardPendingText === 'string' && value.guardPendingText.trim() !== ''\n ? value.guardPendingText\n : localized.guardPendingText;\n const guardDoneText =\n typeof value.guardDoneText === 'string' && value.guardDoneText.trim() !== ''\n ? value.guardDoneText\n : localized.guardDoneText;\n return {\n locale,\n continueText: text,\n continueTextMaxTokens: maxTokensText,\n guardTools: booleanOr(value.guardTools, DEFAULT_CONFIG.guardTools),\n guardPendingText,\n guardDoneText,\n graceMs: numberOr(value.graceMs, DEFAULT_CONFIG.graceMs),\n cooldownMs: numberOr(value.cooldownMs, DEFAULT_CONFIG.cooldownMs),\n maxConsecutive: Math.max(1, numberOr(value.maxConsecutive, DEFAULT_CONFIG.maxConsecutive)),\n scanOnBoot: booleanOr(value.scanOnBoot, DEFAULT_CONFIG.scanOnBoot),\n scanLimit: Math.max(1, numberOr(value.scanLimit, DEFAULT_CONFIG.scanLimit)),\n freshMs: numberOr(value.freshMs, DEFAULT_CONFIG.freshMs),\n verbose: booleanOr(value.verbose, DEFAULT_CONFIG.verbose),\n classify: booleanOr(value.classify, DEFAULT_CONFIG.classify),\n retryableErrorPatterns:\n typeof value.retryableErrorPatterns === 'string'\n ? value.retryableErrorPatterns.trim()\n : DEFAULT_CONFIG.retryableErrorPatterns,\n backoffFactor: Math.max(1, numberOr(value.backoffFactor, DEFAULT_CONFIG.backoffFactor)),\n backoffMaxMs: numberOr(value.backoffMaxMs, DEFAULT_CONFIG.backoffMaxMs),\n notify: booleanOr(value.notify, DEFAULT_CONFIG.notify),\n paused: booleanOr(value.paused, DEFAULT_CONFIG.paused),\n loopGuard: booleanOr(value.loopGuard, DEFAULT_CONFIG.loopGuard),\n loopShortChars: Math.max(1, numberOr(value.loopShortChars, DEFAULT_CONFIG.loopShortChars)),\n loopWindowMs: Math.max(1000, numberOr(value.loopWindowMs, DEFAULT_CONFIG.loopWindowMs)),\n loopShortCount: Math.max(2, numberOr(value.loopShortCount, DEFAULT_CONFIG.loopShortCount)),\n loopRepeatText: Math.max(2, numberOr(value.loopRepeatText, DEFAULT_CONFIG.loopRepeatText)),\n loopToolRepeat: Math.max(2, numberOr(value.loopToolRepeat, DEFAULT_CONFIG.loopToolRepeat)),\n loopText:\n typeof value.loopText === 'string' && value.loopText.trim() !== ''\n ? value.loopText\n : localized.loopText,\n };\n}\n\n/**\n * 视为「非人为中断」的回合结束原因, 用于启动/重连扫描。\n * - `interrupted` 只由崩溃修复在宿主重载时写入(loop 永不实时发出), 因此仅在扫描路径处理;\n * - 实时事件路径只对 `error` / `max-tokens` 自动续跑;\n * - `aborted`(用户停止)与 `blocked`(策略拒绝)永不自动继续。\n */\ntype NonHumanReason = 'error' | 'interrupted' | 'max-tokens';\n\nexport function isNonHumanReason(kind: string): kind is NonHumanReason {\n return kind === 'error' || kind === 'interrupted' || kind === 'max-tokens';\n}\n\n/** 一次回合失败的机器可读事实(turn/end error 的 LlmFailure 载荷)。 */\nexport interface FailureFacts {\n /** 稳定机器路由码(如 UPSTREAM、RATE_LIMIT_EXCEEDED、INVALID_API_KEY)。 */\n code: string;\n /** 人类可读的失败描述。 */\n message: string;\n /** 供应商 HTTP 状态码(可用时)。 */\n status?: number;\n}\n\n/**\n * 错误分类: 该失败是否值得自动继续。\n * 用户填写的 provider 专属文本片段优先覆盖内置结果; 未命中时,\n * 永久性失败(认证/余额/模型不存在/上下文超限等)重试也不会成功, 应跳过并通知用户;\n * 其余(网络、超时、5xx、429 等)视为临时性失败, 允许自动恢复。\n */\nexport function isTransientFailure(failure: FailureFacts, retryableErrorPatterns = ''): boolean {\n const haystack = `${failure.code} ${failure.status ?? ''} ${failure.message}`.toLowerCase();\n const explicitlyRetryable = retryableErrorPatterns\n .split(/\\r?\\n/)\n .map((pattern) => pattern.trim().toLowerCase())\n .filter((pattern) => pattern !== '')\n .some((pattern) => haystack.includes(pattern));\n if (explicitlyRetryable) return true;\n const status = failure.status;\n if (status !== undefined && (status === 401 || status === 403)) return false;\n const permanent =\n /auth|unauthor|forbidden|credential|api[_-]?key|permission/i.test(haystack) ||\n /insufficient.*(balance|quota)|billing|payment|quota.*exceeded.*(?!retry)/i.test(haystack) ||\n /model.*not[_-]?found|unknown[_-]?model|model[_-]?not[_-]?found|not.*support.*model/i.test(haystack) ||\n /context.*(length|limit|overflow|exceed)|token.*limit|max.*context/i.test(haystack) ||\n /invalid[_-]?request|bad[_-]?request/i.test(haystack);\n return !permanent;\n}\n\n/**\n * host/agent-error 消息分类: 仅明确属于网络/传输类的临时错误才自动继续。\n * 其余(序列化失败、配置/宿主内部错误等)视为永久性——重试无益, 且用户停止导致的\n * 序列化失败(如 Windows 下 abort 的 DOMException reason)绝不能自动续跑。\n */\nexport function isTransientAgentError(message: string): boolean {\n return /network|timeout|timed ?out|econn|etimedout|socket|5\\d\\d|\\b429\\b|upstream|temporar/i.test(message);\n}\n\n/** 通知上的一个操作按钮(action 标识 + 显示文案)。 */\nexport interface NotifyAction {\n /** 稳定动作标识, 点击时经 onAction 回调传出。 */\n action: string;\n /** 按钮显示文案。 */\n title: string;\n}\n\n/** 通知的可选行为: 操作按钮列表与点击回调。 */\nexport interface NotifyOptions {\n actions?: NotifyAction[];\n onAction?: (action: string) => void;\n}\n\n/** 浏览器通知(不可用时静默跳过); 点击通知聚焦窗口, 操作按钮走 onAction。 */\n/** 把毫秒格式化为人类可读的经过时长(如 65s → 1m5s)。 */\nfunction formatElapsed(ms: number | undefined): string {\n if (ms === undefined || !Number.isFinite(ms) || ms < 0) return '';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const s = Math.round(ms / 1000);\n if (s < 60) return `${s}s`;\n return `${Math.floor(s / 60)}m${s % 60 > 0 ? `${s % 60}s` : ''}`;\n}\n\n/** 模板填充所需的上下文(全部可选, 缺失的占位符填为空串)。 */\nexport interface TemplateContext {\n /** 失败事实(错误码/消息/HTTP 状态), 对应 {code}/{message}/{status}。 */\n facts?: FailureFacts;\n /** 失败前最后一次工具调用的名称, 对应 {tool}。 */\n tool?: string;\n /** 失败回合的编号, 对应 {turn}。 */\n turn?: number;\n /** 连续失败次数(含本次), 对应 {errorCount}。 */\n errorCount?: number;\n /** 会话标题(来自 session.list 投影, 可用时), 对应 {sessionTitle}。 */\n sessionTitle?: string;\n /** 自失败发生以来的毫秒数, 对应 {elapsed}。 */\n elapsedMs?: number;\n /** 上一步工具结果摘要(截断), 对应 {result}(护栏模板用)。 */\n result?: string;\n}\n\n/** 用失败事实与回合信息填充 continueText 模板占位符({code}/{message}/{status}/{tool}/{turn}/{errorCount}/{sessionTitle}/{elapsed}/{result})。 */\nexport function fillTemplate(template: string, ctx: TemplateContext): string {\n return template\n .replace(/\\{code\\}/g, ctx.facts?.code ?? '')\n .replace(/\\{message\\}/g, ctx.facts?.message ?? '')\n .replace(/\\{status\\}/g, ctx.facts?.status !== undefined ? String(ctx.facts.status) : '')\n .replace(/\\{tool\\}/g, ctx.tool ?? '')\n .replace(/\\{turn\\}/g, ctx.turn !== undefined ? String(ctx.turn) : '')\n .replace(/\\{errorCount\\}/g, ctx.errorCount !== undefined ? String(ctx.errorCount) : '')\n .replace(/\\{sessionTitle\\}/g, ctx.sessionTitle ?? '')\n .replace(/\\{elapsed\\}/g, formatElapsed(ctx.elapsedMs))\n .replace(/\\{result\\}/g, ctx.result ?? '');\n}\n\n// ---------- 幂等护栏: 上一步工具调用的执行状态 ----------\n\n/** 工具结果摘要的最大长度(护栏模板 {result} 用)。 */\nconst TOOL_RESULT_CAP = 160;\n\n/** 从任意内容块里递归收集文本(结果为模型可见的工具输出)。 */\nfunction extractText(blocks: unknown, cap: number): string {\n let out = '';\n const walk = (value: unknown): void => {\n if (out.length >= cap) return;\n if (Array.isArray(value)) {\n for (const item of value) walk(item);\n return;\n }\n if (typeof value !== 'object' || value === null) return;\n const record = value as Record<string, unknown>;\n if (record['type'] === 'text' && typeof record['text'] === 'string') {\n out += record['text'];\n return;\n }\n for (const child of Object.values(record)) walk(child);\n };\n walk(blocks);\n return out.slice(0, cap);\n}\n\n/** 上一步工具调用的判定结果: 是否已确认完成, 以及文本摘要。 */\nexport interface ToolResultFacts {\n /** 工具是否成功完成(内部失败或 isError 视为未成功)。 */\n ok: boolean;\n /** 工具输出的文本摘要(截断)。 */\n excerpt: string;\n}\n\n/** 从 tool/result 事件载荷提取成功与否与文本摘要。 */\nexport function toolResultFacts(data: {\n error?: { name?: string; code?: string };\n message?: { content?: Array<{ type?: string; content?: unknown; isError?: boolean }> };\n}): ToolResultFacts {\n const failed = data.error !== undefined || data.message?.content?.[0]?.isError === true;\n return { ok: !failed, excerpt: extractText(data.message?.content?.[0]?.content, TOOL_RESULT_CAP) };\n}\n\n/** 自适应退避: 同一会话连续失败时的有效冷却间隔。 */\nexport function effectiveCooldown(\n consecutive: number,\n base: number,\n factor: number,\n max: number,\n): number {\n // consecutive = 已连续自动继续的次数; 第 1 次后开始按 factor 递增\n const multiplier = Math.pow(factor, consecutive);\n return Math.min(Math.max(base, base * multiplier), Math.max(base, max));\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** 浏览器当前 IANA 时区; 不可用时省略(宿主允许省略)。 */\nfunction clientTimeZone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || undefined;\n } catch {\n return undefined;\n }\n}\n\n/** 一天的自动继续统计(host 单实例内存态)。 */\nexport interface DayStats {\n /** 本地日期 YYYY-MM-DD。 */\n date: string;\n /** 自动发送次数。 */\n sent: number;\n /** 因永久性错误跳过的次数。 */\n skipped: number;\n /** 发送后回合成功完成(恢复成功)的次数。 */\n recovered: number;\n /** 发送后再次失败的次数。 */\n failed: number;\n /** 达到连续上限而停止的次数(按停止事件计)。 */\n gaveUp: number;\n /** loop guard 打断并重启回合的次数。 */\n looped: number;\n /** 按错误码计数的失败分布。 */\n byCode: Record<string, number>;\n}\n\nexport function todayKey(): string {\n const d = new Date();\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n return `${d.getFullYear()}-${mm}-${dd}`;\n}\n\n/** 空统计桶。 */\nexport function emptyDayStats(): DayStats {\n return { date: todayKey(), sent: 0, skipped: 0, recovered: 0, failed: 0, gaveUp: 0, looped: 0, byCode: {} };\n}\n\n/** 每会话运行时状态。 */\nexport interface SessionState {\n /** 连续自动「继续」次数; 成功回合或用户手动介入后归零。 */\n consecutive: number;\n /** 上次自动「继续」时间戳。 */\n lastAutoAt: number;\n /** 上次自动「继续」尝试(成功或失败)时间戳; 防止失败场景下的快速重试循环。 */\n lastAttemptAt: number;\n /** 我们上次自动发送的文本(用于识别自己的回显)。 */\n lastSentText: string;\n /** 宽限期定时器(进行中的待发送)。 */\n pendingTimer: ReturnType<typeof setTimeout> | undefined;\n /** 宿主权威 running 位(来自 host/session-status 与回合事件)。 */\n running: boolean | undefined;\n /** 当前排队消息数(来自 session/queue 帧)。 */\n queued: number;\n /** 子代理会话(host/session-added 带 parentSessionId)。 */\n subagent: boolean;\n /** 最近一次回合失败的事实(用于分类与模板填充)。 */\n lastFailure: FailureFacts | undefined;\n /** 最近一次失败的发生时间(模板 {elapsed} 与恢复统计用)。 */\n lastFailureAt: number;\n /** 失败前最后一次工具调用的名称(模板 {tool} 与幂等护栏用)。 */\n lastTool: string | undefined;\n /** 上一步工具调用的结果状态: 'pending' = 已发起未见结果(可能已部分执行)。 */\n lastToolResult: 'pending' | ToolResultFacts | undefined;\n /** 失败回合的编号(模板 {turn})。 */\n lastTurn: number | undefined;\n /** 我们最近一次自动发送的时间戳; 0 = 没有待确认的恢复。 */\n pendingRecoveryAt: number;\n /** 当前连续短句数(loop guard 信号 1: 空转)。 */\n shortRun: number;\n /** 最后一条短句的时间(时间窗判定用)。 */\n lastShortAt: number;\n /** 最后一条模型消息的文本(相同文本重复判定用)。 */\n lastAssistantText: string;\n /** 连续相同文本消息数(最强空转信号, 不限长度)。 */\n sameTextRun: number;\n /**\n * 工具重复信号(loop guard 信号 2: 死循环)。\n * 只有「同工具 + 同参数 + 同结果」的连续调用才累计; 参数或结果有变化视为有进展, 计数重置。\n */\n toolRun:\n | {\n /** 工具名 + 参数(用于判定是否同一调用)。 */\n key: string;\n /** 连续相同调用数(结果确认后更新)。 */\n count: number;\n /** 上次该调用的结果摘要(比较用)。 */\n lastResult: string | undefined;\n /** 本次调用等待结果确认。 */\n waiting: boolean;\n }\n | undefined;\n /** 本回合已触发过 loop guard(防重复打断)。 */\n loopFired: boolean;\n /** loop 重启的延迟定时器(冷却结束后再 schedule)。 */\n loopRetryTimer: ReturnType<typeof setTimeout> | undefined;\n /** 我们主动 cancel 过本回合(区分用户停止)。 */\n loopCancelled: boolean;\n}\n\nexport const freshState = (): SessionState => ({\n consecutive: 0,\n lastAutoAt: 0,\n lastAttemptAt: 0,\n lastSentText: '',\n pendingTimer: undefined,\n running: undefined,\n queued: 0,\n subagent: false,\n lastFailure: undefined,\n lastFailureAt: 0,\n lastTool: undefined,\n lastToolResult: undefined,\n lastTurn: undefined,\n pendingRecoveryAt: 0,\n shortRun: 0,\n lastShortAt: 0,\n lastAssistantText: '',\n sameTextRun: 0,\n toolRun: undefined,\n loopFired: false,\n loopCancelled: false,\n loopRetryTimer: undefined,\n});\n\n\nexport const RECOVERY_WINDOW_MS = 10 * 60 * 1000;\n\nexport const ECHO_WINDOW_MS = 10 * 60 * 1000;\n\nexport function isOurEcho(state: SessionState, event: SessionEvent): boolean {\n if (event.type !== 'user/message') return false;\n const message = event.data;\n if (message.source.kind !== 'user') return false;\n if (state.lastSentText === '') return false;\n if (Date.now() - state.lastAutoAt > ECHO_WINDOW_MS) return false;\n const text = message.content\n .filter((part): part is { type: 'text'; text: string } => part.type === 'text')\n .map((part) => part.text)\n .join('');\n return text === state.lastSentText;\n}\n", "/**\n * `auto-continue` namespace dictionaries: copy for the plugin settings card\n * registered into the `settings.plugin.item` seat of the plugin-configuration\n * section. Includes the card-chrome keys the card component reads.\n */\nimport { LOCALIZED_TEXT_DEFAULTS } from '../shared/core.ts';\n\n/** 简体中文词典(键集的事实来源)。 */\nexport const zh = {\n 'card.title': '自动继续',\n 'card.eyebrow': '中断接力器',\n 'card.description': '接住意外中断的请求,等现场稳定下来,再把对话交还给 Agent。',\n 'flow.interrupted': '检测中断',\n 'flow.grace': '安全等待',\n 'flow.continue': '发送继续',\n 'repo.star': '去 GitHub 点 Star',\n 'repo.aria': '打开 dsh-auto-continue 的 GitHub 开源地址并点 Star',\n 'section.handoff.title': '接力方式',\n 'section.handoff.description': '决定中断后说什么,以及什么时候暂时停手。',\n 'section.safety.title': '安全节奏',\n 'section.safety.description': '先确认上一步,再控制等待与连续续跑的边界。',\n 'section.recovery.title': '恢复雷达',\n 'section.recovery.description': '扫描掉线会话,识别可恢复错误并逐步退避。',\n 'section.loop.title': '循环断路器',\n 'section.loop.description': '发现空转时及时换路,而不是让 Agent 原地消耗。',\n 'section.live.title': '现场状态',\n 'section.live.description': '看看今天接住了多少次,以及哪些会话还在暂停。',\n 'field.paused': '暂停自动继续',\n 'field.pausedHint': '全局暂停: 实时与扫描都不会再自动发送, 已排队的待发送也会取消。',\n 'field.continueText': '继续文本',\n 'field.continueTextHint': '中断后自动发送的消息内容。',\n 'default.continueText': LOCALIZED_TEXT_DEFAULTS.zh.continueText,\n 'field.continueTextMaxTokens': '超限时的继续文本',\n 'field.continueTextMaxTokensHint': '达到输出 token 上限时自动发送的文本, 支持与继续文本相同的占位符。',\n 'default.continueTextMaxTokens': LOCALIZED_TEXT_DEFAULTS.zh.continueTextMaxTokens,\n 'field.guardTools': '幂等护栏',\n 'field.guardToolsHint': '续跑前检查上一步工具调用: 结果未确认时提示先确认状态, 已成功时提示不要重复执行, 避免重复 commit/调 API。',\n 'field.guardPendingText': '结果未确认时的护栏文本',\n 'field.guardPendingTextHint': '上一步工具可能已部分执行时附加到继续文本之后, 支持 {tool} 占位符。',\n 'default.guardPendingText': LOCALIZED_TEXT_DEFAULTS.zh.guardPendingText,\n 'field.guardDoneText': '工具已成功时的护栏文本',\n 'field.guardDoneTextHint': '上一步工具已确认成功时附加到继续文本之后, 支持 {tool} 与 {result}(结果摘要)占位符。',\n 'default.guardDoneText': LOCALIZED_TEXT_DEFAULTS.zh.guardDoneText,\n 'field.graceMs': '宽限期 (ms)',\n 'field.graceMsHint': '检测到中断后等待的时长; 期间宿主自行恢复则取消。',\n 'field.cooldownMs': '冷却时间 (ms)',\n 'field.cooldownMsHint': '同一会话两次自动「继续」的最小间隔, 失败尝试也计入。',\n 'field.maxConsecutive': '最大连续次数',\n 'field.maxConsecutiveHint': '同一会话连续自动「继续」的上限; 超过后停止, 直到用户手动介入或出现成功回合。',\n 'field.scanOnBoot': '启动/重连扫描',\n 'field.scanOnBootHint': '页面启动或重连时扫描最近中断的会话并自动续跑(如浏览器关闭期间宿主崩溃)。',\n 'field.scanLimit': '扫描会话数',\n 'field.scanLimitHint': '最多检查多少个最近更新的会话(不含运行中与子代理会话)。',\n 'field.freshMs': '扫描时间窗 (ms)',\n 'field.freshMsHint': '扫描只处理该时间窗内的中断。',\n 'field.verbose': '详细日志',\n 'field.verboseHint': '在浏览器控制台输出 [auto-continue] 日志。',\n 'field.classify': '错误分类',\n 'field.classifyHint': '仅自动恢复临时性错误(网络/超时/5xx 等); 认证/余额/模型不存在等永久性错误跳过并通知。',\n 'field.retryableErrorPatterns': '自定义可恢复错误',\n 'field.retryableErrorPatternsHint': '每行一个大小写不敏感的普通文本片段; 命中错误码、HTTP 状态或消息时覆盖内置分类。请只填 provider 稳定且足够具体的文案, 过宽会重复请求。',\n 'field.retryableErrorPatternsPlaceholder': '例如:Upstream rejected the request as invalid',\n 'field.backoffFactor': '退避系数',\n 'field.backoffFactorHint': '连续失败时冷却间隔的倍率(如 2 表示 20s→40s→80s 递增)。',\n 'field.backoffMaxMs': '最大退避间隔 (ms)',\n 'field.backoffMaxMsHint': '自适应退避的上限, 防止等待过久。',\n 'field.notify': '浏览器通知',\n 'field.notifyHint': '自动继续成功/放弃/遇到永久性错误时弹出浏览器通知, 通知带「立即续跑」与「暂停该会话 1 小时」按钮。',\n 'stats.title': '今日统计',\n 'stats.sent': '自动继续',\n 'stats.skipped': '跳过(永久错误)',\n 'stats.recovered': '恢复成功',\n 'stats.failed': '继续后仍失败',\n 'stats.gaveUp': '停止(达上限)',\n 'stats.looped': '循环打断',\n 'field.loopGuard': '循环守卫',\n 'field.loopGuardHint': '检测运行中的回合空转: 连续短句且无工具调用, 或连续调用相同工具时, 自动取消并用循环提示文本重启回合。',\n 'field.loopShortChars': '短句长度上限 (字符)',\n 'field.loopShortCharsHint': '模型消息文本短于该值计为一条短句(空转信号)。',\n 'field.loopWindowMs': '短句时间窗 (ms)',\n 'field.loopWindowMsHint': '连续短句必须落在这个时间窗内; 正常思考的短文本散布在长时间里不会被误判。',\n 'field.loopShortCount': '连续短句阈值',\n 'field.loopShortCountHint': '时间窗内连续多少条短句且期间无工具调用时判定空转循环。',\n 'field.loopRepeatText': '相同消息重复次数',\n 'field.loopRepeatTextHint': '连续输出多少条完全相同的消息时判定空转(最强信号, 不限长度, 如模型反复说同一句话)。',\n 'field.loopToolRepeat': '同工具重复次数',\n 'field.loopToolRepeatHint': '同工具+同参数+同结果的连续调用多少次时判定死循环; 参数或结果有变化视为有进展。',\n 'field.loopText': '循环提示文本',\n 'field.loopTextHint': '打断后重启回合时发送的文本, 支持 {tool} 占位符。',\n 'default.loopText': LOCALIZED_TEXT_DEFAULTS.zh.loopText,\n 'stats.byCode': '按错误码统计',\n 'stats.empty': '今天还没有自动继续记录。',\n 'stats.reset': '清零',\n 'pause.title': '已暂停会话',\n 'pause.none': '没有暂停中的会话。',\n 'pause.clearAll': '全部解除',\n 'pause.unpause': '解除',\n 'pause.minutes': '分钟',\n 'chrome.collapse': '收起设置',\n 'chrome.expand': '展开设置',\n 'chrome.unsaved': '未保存',\n 'chrome.readOnly': '当前部署的设置只读。',\n 'chrome.saveFailed': '部署未接受这些值, 已保留供你修改。',\n 'chrome.discard': '放弃',\n 'chrome.saving': '保存中…',\n 'chrome.save': '保存',\n 'chrome.overridden': '已覆盖',\n 'chrome.reset': '恢复默认',\n 'chrome.invalidNumber': '请输入数字, 留空则使用默认值。',\n 'chrome.inherit': '继承',\n 'chrome.on': '开',\n 'chrome.off': '关',\n} satisfies Record<string, string>;\n\n/** 本插件的键联合。 */\nexport type SettingsCardKey = keyof typeof zh;\n\n/** English dictionary, checked complete against the zh key set. */\nexport const en: Record<SettingsCardKey, string> = {\n 'card.title': 'Auto continue',\n 'card.eyebrow': 'Continuity relay',\n 'card.description': 'Catches an interrupted request, waits for things to settle, then hands the thread back to the agent.',\n 'flow.interrupted': 'Interrupted',\n 'flow.grace': 'Safe pause',\n 'flow.continue': 'Continue',\n 'repo.star': 'Star on GitHub',\n 'repo.aria': 'Open the dsh-auto-continue repository on GitHub and star it',\n 'section.handoff.title': 'The handoff',\n 'section.handoff.description': 'Choose what gets sent after an interruption and when the relay should stand down.',\n 'section.safety.title': 'Safety rhythm',\n 'section.safety.description': 'Confirm the previous step, then set the boundaries for waiting and repeated resumes.',\n 'section.recovery.title': 'Recovery radar',\n 'section.recovery.description': 'Find dropped sessions, recognize recoverable errors, and back off gracefully.',\n 'section.loop.title': 'Loop breaker',\n 'section.loop.description': 'Spot a spinning agent and route it forward before it burns time in place.',\n 'section.live.title': 'Live signal',\n 'section.live.description': 'See what the relay caught today and which sessions are still paused.',\n 'field.paused': 'Pause auto-continue',\n 'field.pausedHint': 'Globally pause: no live or scan auto-send fires, and queued pending sends are cancelled.',\n 'field.continueText': 'Continue text',\n 'field.continueTextHint': 'Message automatically sent after an interruption.',\n 'default.continueText': LOCALIZED_TEXT_DEFAULTS.en.continueText,\n 'field.continueTextMaxTokens': 'Continue text (max tokens)',\n 'field.continueTextMaxTokensHint': 'Text sent when the output token ceiling is reached; same placeholders as the continue text.',\n 'default.continueTextMaxTokens': LOCALIZED_TEXT_DEFAULTS.en.continueTextMaxTokens,\n 'field.guardTools': 'Idempotency guard',\n 'field.guardToolsHint': 'Before resuming, inspect the last tool call: if its result is unconfirmed, tell the model to check state first; if it succeeded, tell it not to rerun — avoids duplicate commits / API calls.',\n 'field.guardPendingText': 'Guard text (unconfirmed result)',\n 'field.guardPendingTextHint': 'Appended when the last tool may have partially executed; supports the {tool} placeholder.',\n 'default.guardPendingText': LOCALIZED_TEXT_DEFAULTS.en.guardPendingText,\n 'field.guardDoneText': 'Guard text (tool succeeded)',\n 'field.guardDoneTextHint': 'Appended when the last tool is confirmed done; supports {tool} and {result} (result excerpt).',\n 'default.guardDoneText': LOCALIZED_TEXT_DEFAULTS.en.guardDoneText,\n 'field.graceMs': 'Grace period (ms)',\n 'field.graceMsHint': 'Wait after an interruption; cancelled if the host recovers on its own.',\n 'field.cooldownMs': 'Cooldown (ms)',\n 'field.cooldownMsHint': 'Minimum interval between auto-continues per session; failed attempts count too.',\n 'field.maxConsecutive': 'Max consecutive',\n 'field.maxConsecutiveHint': 'Max consecutive auto-continues per session; stops until a user intervenes or a turn completes.',\n 'field.scanOnBoot': 'Scan on load / reconnect',\n 'field.scanOnBootHint': 'Scan recently interrupted sessions on page load or reconnect (e.g. the host crashed while the browser was closed).',\n 'field.scanLimit': 'Scan limit',\n 'field.scanLimitHint': 'How many most-recently-updated sessions to check (running / subagent sessions excluded).',\n 'field.freshMs': 'Scan window (ms)',\n 'field.freshMsHint': 'Only interruptions inside this window are considered.',\n 'field.verbose': 'Verbose logs',\n 'field.verboseHint': 'Log [auto-continue] lines to the browser console.',\n 'field.classify': 'Classify errors',\n 'field.classifyHint': 'Auto-resume transient failures only (network/timeout/5xx…); auth, balance and model errors are skipped and notified.',\n 'field.retryableErrorPatterns': 'Custom retryable errors',\n 'field.retryableErrorPatternsHint': 'One case-insensitive literal per line. A match in the error code, HTTP status, or message overrides built-in classification. Use only stable, provider-specific text; broad matches can repeat requests.',\n 'field.retryableErrorPatternsPlaceholder': 'For example: Upstream rejected the request as invalid',\n 'field.backoffFactor': 'Backoff factor',\n 'field.backoffFactorHint': 'Cooldown multiplier per consecutive failure (2 = 20s→40s→80s…).',\n 'field.backoffMaxMs': 'Max backoff (ms)',\n 'field.backoffMaxMsHint': 'Cap on the adaptive backoff interval.',\n 'field.notify': 'Browser notifications',\n 'field.notifyHint': 'Notify when auto-continue fires, gives up, or hits a permanent error; notifications carry \"Resume now\" and \"Pause this session 1h\" buttons.',\n 'stats.title': \"Today's stats\",\n 'stats.sent': 'Auto-continued',\n 'stats.skipped': 'Skipped (permanent)',\n 'stats.recovered': 'Recovered',\n 'stats.failed': 'Failed after',\n 'stats.gaveUp': 'Gave up (cap)',\n 'stats.looped': 'Loops broken',\n 'field.loopGuard': 'Loop guard',\n 'field.loopGuardHint': 'Detects a running turn spinning in place — many short sentences with no tool calls, or the same tool repeating — cancels it and restarts with the loop text.',\n 'field.loopShortChars': 'Short-sentence max (chars)',\n 'field.loopShortCharsHint': 'A model message shorter than this counts as a short sentence (spinning signal).',\n 'field.loopWindowMs': 'Short-sentence window (ms)',\n 'field.loopWindowMsHint': 'Consecutive short sentences must land inside this window; normal thinking spread over time is not misjudged.',\n 'field.loopShortCount': 'Short-sentence threshold',\n 'field.loopShortCountHint': 'How many consecutive short sentences inside the window, with no tool call, trip the loop guard.',\n 'field.loopRepeatText': 'Identical message count',\n 'field.loopRepeatTextHint': 'How many consecutive identical messages trip the guard (strongest signal, any length, e.g. the model repeating the same line).',\n 'field.loopToolRepeat': 'Same-tool repeat count',\n 'field.loopToolRepeatHint': 'How many consecutive calls of the same tool with identical arguments and results trip the loop guard; a changed argument or result counts as progress.',\n 'field.loopText': 'Loop text',\n 'field.loopTextHint': 'Text sent after the loop guard restarts a turn; supports the {tool} placeholder.',\n 'default.loopText': LOCALIZED_TEXT_DEFAULTS.en.loopText,\n 'stats.byCode': 'By error code',\n 'stats.empty': 'No auto-continue activity today.',\n 'stats.reset': 'Reset',\n 'pause.title': 'Paused sessions',\n 'pause.none': 'No sessions paused.',\n 'pause.clearAll': 'Clear all',\n 'pause.unpause': 'Resume',\n 'pause.minutes': 'min',\n 'chrome.collapse': 'Hide settings',\n 'chrome.expand': 'Show settings',\n 'chrome.unsaved': 'Unsaved',\n 'chrome.readOnly': 'This deployment stores settings read-only.',\n 'chrome.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'chrome.discard': 'Discard',\n 'chrome.saving': 'Saving…',\n 'chrome.save': 'Save',\n 'chrome.overridden': 'Overridden',\n 'chrome.reset': 'Reset to default',\n 'chrome.invalidNumber': 'Enter a number, or leave blank to use the default.',\n 'chrome.inherit': 'Inherit',\n 'chrome.on': 'On',\n 'chrome.off': 'Off',\n};\n", "/**\n * The auto-continue settings card: edits the `auto-continue` namespace fields\n * from the plugin-configuration section (the `settings.plugin.item` seat).\n *\n * Self-contained card chrome (disclosure header, staged fields, save/discard\n * footer) following the plugin-card store pattern of the DSH plugin\n * configuration section; styles live in `styles.ts` and use the DSH design\n * tokens so the card follows the active theme.\n */\nimport { useEffect, useState, type ReactNode } from 'react';\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';\nimport { type AutoContinueSettings } from './engine.ts';\nimport { createSnapshotStore, type SettingsScope, type SnapshotStore } from './dsh-store-compat.ts';\nimport {\n pausedSessions,\n readTodayStats,\n resetTodayStats,\n subscribeBridge,\n unpauseSession,\n} from './bridge.ts';\nimport type { SettingsCardKey } from './locales.ts';\nimport {\n booleanField,\n CardForm,\n numberField,\n textField,\n type CardActions,\n type CardFieldState,\n type CardShell,\n} from './settings-form.ts';\nimport { injectStyles } from './styles.ts';\n\n// Styles must land during factory materialization so the module system's\n// style bookkeeping (HMR) owns them.\ninjectStyles();\n\n/** What the auto-continue card renders. */\nexport interface AutoContinueSettingsCardState extends CardShell {\n paused: CardFieldState;\n continueText: CardFieldState;\n continueTextMaxTokens: CardFieldState;\n guardTools: CardFieldState;\n guardPendingText: CardFieldState;\n guardDoneText: CardFieldState;\n graceMs: CardFieldState;\n cooldownMs: CardFieldState;\n maxConsecutive: CardFieldState;\n scanOnBoot: CardFieldState;\n scanLimit: CardFieldState;\n freshMs: CardFieldState;\n verbose: CardFieldState;\n classify: CardFieldState;\n retryableErrorPatterns: CardFieldState;\n backoffFactor: CardFieldState;\n backoffMaxMs: CardFieldState;\n notify: CardFieldState;\n loopGuard: CardFieldState;\n loopShortChars: CardFieldState;\n loopWindowMs: CardFieldState;\n loopShortCount: CardFieldState;\n loopRepeatText: CardFieldState;\n loopToolRepeat: CardFieldState;\n loopText: CardFieldState;\n}\n\n/** The registration-side face the card's slot entry injects. */\nexport interface AutoContinueSettingsCardFace extends CardActions {\n hooks: {\n /** Card snapshot bound by the renderer as useAutoContinueSettingsCard. */\n autoContinueSettingsCard: SnapshotStore<AutoContinueSettingsCardState>;\n };\n}\n\n/** Bridges the `auto-continue` scope onto the card's staged form. */\nexport class AutoContinueSettingsCardController {\n private readonly form: CardForm<AutoContinueSettings>;\n private readonly store: SnapshotStore<AutoContinueSettingsCardState>;\n\n /**\n * @param scope - the bound settings scope for the `auto-continue` namespace.\n */\n constructor(scope: SettingsScope<AutoContinueSettings>) {\n this.form = new CardForm(scope, [\n booleanField('paused'),\n textField('continueText'),\n textField('continueTextMaxTokens'),\n booleanField('guardTools'),\n textField('guardPendingText'),\n textField('guardDoneText'),\n numberField('graceMs', 0),\n numberField('cooldownMs', 0),\n numberField('maxConsecutive', 1),\n booleanField('scanOnBoot'),\n numberField('scanLimit', 1),\n numberField('freshMs', 0),\n booleanField('verbose'),\n booleanField('classify'),\n textField('retryableErrorPatterns'),\n numberField('backoffFactor', 1),\n numberField('backoffMaxMs', 0),\n booleanField('notify'),\n booleanField('loopGuard'),\n numberField('loopShortChars', 1),\n numberField('loopWindowMs', 1000),\n numberField('loopShortCount', 2),\n numberField('loopRepeatText', 2),\n numberField('loopToolRepeat', 2),\n textField('loopText'),\n ]);\n this.store = this.form.bind(() => this.projection(), createSnapshotStore);\n }\n\n private projection(): AutoContinueSettingsCardState {\n return {\n ...this.form.shell(),\n paused: this.form.field('paused'),\n continueText: this.form.field('continueText'),\n continueTextMaxTokens: this.form.field('continueTextMaxTokens'),\n guardTools: this.form.field('guardTools'),\n guardPendingText: this.form.field('guardPendingText'),\n guardDoneText: this.form.field('guardDoneText'),\n graceMs: this.form.field('graceMs'),\n cooldownMs: this.form.field('cooldownMs'),\n maxConsecutive: this.form.field('maxConsecutive'),\n scanOnBoot: this.form.field('scanOnBoot'),\n scanLimit: this.form.field('scanLimit'),\n freshMs: this.form.field('freshMs'),\n verbose: this.form.field('verbose'),\n classify: this.form.field('classify'),\n retryableErrorPatterns: this.form.field('retryableErrorPatterns'),\n backoffFactor: this.form.field('backoffFactor'),\n backoffMaxMs: this.form.field('backoffMaxMs'),\n notify: this.form.field('notify'),\n loopGuard: this.form.field('loopGuard'),\n loopShortChars: this.form.field('loopShortChars'),\n loopWindowMs: this.form.field('loopWindowMs'),\n loopShortCount: this.form.field('loopShortCount'),\n loopRepeatText: this.form.field('loopRepeatText'),\n loopToolRepeat: this.form.field('loopToolRepeat'),\n loopText: this.form.field('loopText'),\n };\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot and its form actions.\n */\n inject(): AutoContinueSettingsCardFace {\n return { hooks: { autoContinueSettingsCard: this.store }, ...this.form.actions() };\n }\n}\n\n/** Props the renderer binds for the auto-continue plugin-configuration card. */\nexport type AutoContinueSettingsCardProps =\n PropsRuntime<'settings.plugin.item'> & PropsLocale<'auto-continue'> & InjectFace<AutoContinueSettingsCardFace>;\n\nconst REPOSITORY_URL = 'https://github.com/HsiangNianian/dsh-auto-continue';\nconst REPOSITORY_SLUG = 'HsiangNianian/dsh-auto-continue';\n\nfunction RelayMark() {\n return (\n <svg viewBox=\"0 0 48 48\" aria-hidden=\"true\" focusable=\"false\">\n <path className=\"dshAcRelayArc\" d=\"M9 30c4-12 10-18 19-18 5 0 9 2 12 6\" />\n <path className=\"dshAcRelayArc dshAcRelayArcEcho\" d=\"M8 35c6 3 12 3 17 0 5-3 8-8 15-9\" />\n <circle className=\"dshAcRelayNode dshAcRelayNodeStart\" cx=\"9\" cy=\"30\" r=\"3\" />\n <circle className=\"dshAcRelayNode dshAcRelayNodeEnd\" cx=\"40\" cy=\"18\" r=\"3\" />\n <circle className=\"dshAcRelayPulse\" cx=\"28\" cy=\"12\" r=\"2.5\" />\n </svg>\n );\n}\n\nfunction ChevronMark() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"m3.5 6 4.5 4 4.5-4\" />\n </svg>\n );\n}\n\nfunction GitHubMark() {\n return (\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M12 2.4a9.8 9.8 0 0 0-3.1 19.1c.5.1.7-.2.7-.5v-1.9c-2.8.6-3.4-1.2-3.4-1.2-.5-1.1-1.1-1.4-1.1-1.4-.9-.6.1-.6.1-.6 1 0 1.5 1 1.5 1 .9 1.5 2.3 1.1 2.9.8.1-.6.4-1.1.6-1.3-2.2-.3-4.6-1.1-4.6-4.9 0-1.1.4-2 1-2.7-.1-.3-.4-1.3.1-2.7 0 0 .8-.3 2.8 1a9.5 9.5 0 0 1 5 0c1.9-1.3 2.8-1 2.8-1 .5 1.4.2 2.4.1 2.7.6.7 1 1.6 1 2.7 0 3.8-2.3 4.6-4.6 4.9.4.3.7.9.7 1.8V21c0 .3.2.6.7.5A9.8 9.8 0 0 0 12 2.4Z\" />\n </svg>\n );\n}\n\nfunction ExternalMark() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M6 3h7v7M13 3 7 9\" />\n <path d=\"M11 9v3a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h3\" />\n </svg>\n );\n}\n\nfunction RelayJourney(props: { t: (key: SettingsCardKey) => string }) {\n return (\n <span className=\"dshAcJourney\">\n <span className=\"dshAcJourneyStep dshAcJourneyInterrupted\">\n <span className=\"dshAcJourneyDot\" aria-hidden=\"true\" />\n {props.t('flow.interrupted')}\n </span>\n <span className=\"dshAcJourneyLine\" aria-hidden=\"true\" />\n <span className=\"dshAcJourneyStep dshAcJourneyGrace\">\n <span className=\"dshAcJourneyDot\" aria-hidden=\"true\" />\n {props.t('flow.grace')}\n </span>\n <span className=\"dshAcJourneyLine\" aria-hidden=\"true\" />\n <span className=\"dshAcJourneyStep dshAcJourneyContinue\">\n <span className=\"dshAcJourneyDot\" aria-hidden=\"true\" />\n {props.t('flow.continue')}\n </span>\n </span>\n );\n}\n\n/** Card chrome: a disclosure header naming the plugin and what its settings govern, the controls, and the save that writes them. */\nfunction SettingsCard(props: {\n t: (key: SettingsCardKey) => string;\n titleKey: SettingsCardKey;\n descriptionKey: SettingsCardKey;\n state: CardShell;\n onSave: () => void;\n onDiscard: () => void;\n children: ReactNode;\n}) {\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 ? 'dshAcCard dshAcCardOpen' : 'dshAcCard'}>\n <div className=\"dshAcHeaderFrame\">\n <button\n type=\"button\"\n className=\"dshAcHeader\"\n aria-expanded={open}\n aria-label={`${props.t(open ? 'chrome.collapse' : 'chrome.expand')}: ${title}`}\n title={props.t(props.descriptionKey)}\n onClick={() => setOpen(!open)}\n >\n <span className=\"dshAcRelayMark\"><RelayMark /></span>\n <span className=\"dshAcHeadText\">\n <span className=\"dshAcEyebrow\">{props.t('card.eyebrow')}</span>\n <span className=\"dshAcName\">{title}</span>\n <span className=\"dshAcDescription\">{props.t(props.descriptionKey)}</span>\n <RelayJourney t={props.t} />\n </span>\n {state.dirty ? (\n <span className=\"dshAcPending\" title={props.t('chrome.unsaved')}>\n {props.t('chrome.unsaved')}\n </span>\n ) : null}\n <span className={open ? 'dshAcChevron dshAcChevronOpen' : 'dshAcChevron'}>\n <ChevronMark />\n </span>\n </button>\n <a\n className=\"dshAcGithub\"\n href={REPOSITORY_URL}\n target=\"_blank\"\n rel=\"noreferrer\"\n aria-label={props.t('repo.aria')}\n >\n <span className=\"dshAcGithubIcon\"><GitHubMark /></span>\n <span className=\"dshAcGithubText\">\n <span className=\"dshAcGithubAction\">{props.t('repo.star')}</span>\n <span className=\"dshAcGithubSlug\">{REPOSITORY_SLUG}</span>\n </span>\n <span className=\"dshAcExternal\"><ExternalMark /></span>\n </a>\n </div>\n {open ? (\n <div className=\"dshAcBody\">\n {!state.writable ? (\n <p className=\"dshAcReadOnly\" role=\"status\">{props.t('chrome.readOnly')}</p>\n ) : null}\n {props.children}\n <div className=\"dshAcFooter\">\n {state.failed ? (\n <p className=\"dshAcFailed\" role=\"status\">{props.t('chrome.saveFailed')}</p>\n ) : null}\n <button\n type=\"button\"\n className=\"dshAcDiscard\"\n disabled={!state.dirty || state.saving}\n onClick={props.onDiscard}\n >\n {props.t('chrome.discard')}\n </button>\n <button type=\"button\" className=\"dshAcSave\" disabled={blocked} onClick={props.onSave}>\n {props.t(!state.saving ? 'chrome.save' : 'chrome.saving')}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n );\n}\n\n/** Props every field control needs regardless of its value type. */\ninterface FieldProps {\n id: string;\n label: string;\n hint: string;\n wide?: boolean;\n text: string;\n overridden: boolean;\n invalid: boolean;\n disabled: boolean;\n t: (key: SettingsCardKey) => string;\n onEdit: (text: string) => void;\n onReset: () => void;\n}\n\n/** A staged value field; `numeric` only hints the keypad, which drafts a field accepts is decided by its spec. */\nfunction ValueField(props: FieldProps & { numeric?: boolean; multiline?: boolean; placeholder?: string }) {\n const className = props.invalid ? 'dshAcInput dshAcInputInvalid' : 'dshAcInput';\n return (\n <div className={props.wide === true ? 'dshAcField dshAcFieldWide' : 'dshAcField'}>\n <div className=\"dshAcHead\">\n <label className=\"dshAcLabel\" htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className=\"dshAcBadges\">\n <span className=\"dshAcBadge\">{props.t('chrome.overridden')}</span>\n <button type=\"button\" className=\"dshAcReset\" disabled={props.disabled} onClick={props.onReset}>\n {props.t('chrome.reset')}\n </button>\n </span>\n ) : null}\n </div>\n {props.multiline === true ? (\n <textarea\n id={props.id}\n className={`${className} dshAcTextArea`}\n aria-invalid={props.invalid || undefined}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n rows={4}\n onChange={(event) => props.onEdit(event.target.value)}\n />\n ) : (\n <input\n id={props.id}\n className={className}\n type=\"text\"\n inputMode={props.numeric === true ? 'numeric' : undefined}\n aria-invalid={props.invalid || undefined}\n value={props.text}\n placeholder={props.placeholder ?? ''}\n disabled={props.disabled}\n onChange={(event) => props.onEdit(event.target.value)}\n />\n )}\n <p className={props.invalid ? 'dshAcInvalid' : 'dshAcHint'}>\n {props.invalid ? props.t('chrome.invalidNumber') : props.hint}\n </p>\n </div>\n );\n}\n\n/** A staged boolean field: inherit / on / off. */\nfunction BooleanField(props: FieldProps) {\n return (\n <div className={props.wide === true ? 'dshAcField dshAcFieldWide' : 'dshAcField'}>\n <div className=\"dshAcHead\">\n <label className=\"dshAcLabel\" htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className=\"dshAcBadges\">\n <span className=\"dshAcBadge\">{props.t('chrome.overridden')}</span>\n <button type=\"button\" className=\"dshAcReset\" disabled={props.disabled} onClick={props.onReset}>\n {props.t('chrome.reset')}\n </button>\n </span>\n ) : null}\n </div>\n <select\n id={props.id}\n className=\"dshAcSelect\"\n value={props.text}\n disabled={props.disabled}\n onChange={(event) => props.onEdit(event.target.value)}\n >\n <option value=\"\">{props.t('chrome.inherit')}</option>\n <option value=\"true\">{props.t('chrome.on')}</option>\n <option value=\"false\">{props.t('chrome.off')}</option>\n </select>\n <p className=\"dshAcHint\">{props.hint}</p>\n </div>\n );\n}\n\ntype SettingsSectionTone = 'handoff' | 'safety' | 'recovery' | 'loop' | 'live';\n\n/** A real behavior group, not a decorative divider: each section maps to one phase of the relay. */\nfunction SettingsSection(props: {\n t: (key: SettingsCardKey) => string;\n titleKey: SettingsCardKey;\n descriptionKey: SettingsCardKey;\n tone: SettingsSectionTone;\n children: ReactNode;\n}) {\n return (\n <section className={`dshAcFormSection dshAcFormSection-${props.tone}`}>\n <header className=\"dshAcSectionHead\">\n <span className=\"dshAcSectionSignal\" aria-hidden=\"true\" />\n <span className=\"dshAcSectionCopy\">\n <span className=\"dshAcSectionTitle\">{props.t(props.titleKey)}</span>\n <span className=\"dshAcSectionDescription\">{props.t(props.descriptionKey)}</span>\n </span>\n </header>\n <div className=\"dshAcSectionGrid\">{props.children}</div>\n </section>\n );\n}\n\n/** 实时面板: 今日统计 + 已暂停会话。浏览器本地状态, 每 5 秒刷新一次。 */\nfunction LivePanels(props: { t: (key: SettingsCardKey) => string }) {\n const { t } = props;\n const [, refresh] = useState(0);\n useEffect(() => {\n // host 状态桥推送时刷新; 5 秒轮询兜底(桥短暂断线时)\n const unsubscribe = subscribeBridge(() => refresh((value) => value + 1));\n const timer = setInterval(() => refresh((value) => value + 1), 5000);\n return () => {\n unsubscribe();\n clearInterval(timer);\n };\n }, []);\n const stats = readTodayStats();\n const hasStats = stats.sent + stats.skipped + stats.recovered + stats.failed + stats.gaveUp + stats.looped > 0;\n const codes = Object.entries(stats.byCode)\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5);\n const paused = pausedSessions();\n return (\n <>\n <section className=\"dshAcPanel\">\n <div className=\"dshAcPanelHead\">\n <span className=\"dshAcPanelTitle\">{t('stats.title')}</span>\n {hasStats ? (\n <button\n type=\"button\"\n className=\"dshAcReset\"\n onClick={() => {\n resetTodayStats();\n refresh((value) => value + 1);\n }}\n >\n {t('stats.reset')}\n </button>\n ) : null}\n </div>\n {!hasStats ? (\n <p className=\"dshAcHint\">{t('stats.empty')}</p>\n ) : (\n <>\n <dl className=\"dshAcStats\">\n <div><dt>{t('stats.sent')}</dt><dd>{stats.sent}</dd></div>\n <div><dt>{t('stats.recovered')}</dt><dd>{stats.recovered}</dd></div>\n <div><dt>{t('stats.failed')}</dt><dd>{stats.failed}</dd></div>\n <div><dt>{t('stats.skipped')}</dt><dd>{stats.skipped}</dd></div>\n <div><dt>{t('stats.gaveUp')}</dt><dd>{stats.gaveUp}</dd></div>\n <div><dt>{t('stats.looped')}</dt><dd>{stats.looped}</dd></div>\n </dl>\n {codes.length > 0 ? (\n <div className=\"dshAcCodes\">\n <span className=\"dshAcHint\">{t('stats.byCode')}:</span>\n {codes.map(([code, count]) => (\n <span key={code} className=\"dshAcCode\">\n {code} ×{count}\n </span>\n ))}\n </div>\n ) : null}\n </>\n )}\n </section>\n <section className=\"dshAcPanel\">\n <div className=\"dshAcPanelHead\">\n <span className=\"dshAcPanelTitle\">{t('pause.title')}</span>\n {paused.length > 0 ? (\n <button\n type=\"button\"\n className=\"dshAcReset\"\n onClick={() => {\n for (const item of paused) unpauseSession(item.sessionId);\n refresh((value) => value + 1);\n }}\n >\n {t('pause.clearAll')}\n </button>\n ) : null}\n </div>\n {paused.length === 0 ? (\n <p className=\"dshAcHint\">{t('pause.none')}</p>\n ) : (\n <ul className=\"dshAcPauseList\">\n {paused.map((item) => (\n <li key={item.sessionId}>\n <span className=\"dshAcPauseId\">{item.sessionId.slice(0, 8)}…</span>\n <span className=\"dshAcHint\">\n {Math.max(1, Math.ceil((item.until - Date.now()) / 60000))} {t('pause.minutes')}\n </span>\n <button\n type=\"button\"\n className=\"dshAcReset\"\n onClick={() => {\n unpauseSession(item.sessionId);\n refresh((value) => value + 1);\n }}\n >\n {t('pause.unpause')}\n </button>\n </li>\n ))}\n </ul>\n )}\n </section>\n </>\n );\n}\n\n/**\n * Render the auto-continue card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function AutoContinueSettingsCard(props: AutoContinueSettingsCardProps) {\n const { t } = props;\n const state = props.useAutoContinueSettingsCard((snapshot) => snapshot);\n const disabled = !state.writable;\n const shared = { t, disabled };\n return (\n <SettingsCard\n t={t}\n titleKey=\"card.title\"\n descriptionKey=\"card.description\"\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <div className=\"dshAcFormCanvas\">\n <SettingsSection\n t={t}\n titleKey=\"section.handoff.title\"\n descriptionKey=\"section.handoff.description\"\n tone=\"handoff\"\n >\n <BooleanField\n wide\n id=\"auto-continue-paused\"\n label={t('field.paused')}\n hint={t('field.pausedHint')}\n {...shared}\n {...state.paused}\n onEdit={(text) => props.edit('paused', text)}\n onReset={() => props.resetField('paused')}\n />\n <ValueField\n id=\"auto-continue-continue-text\"\n label={t('field.continueText')}\n hint={t('field.continueTextHint')}\n {...shared}\n {...state.continueText}\n onEdit={(text) => props.edit('continueText', text)}\n placeholder={t('default.continueText')}\n onReset={() => props.resetField('continueText')}\n />\n <ValueField\n id=\"auto-continue-continue-text-max-tokens\"\n label={t('field.continueTextMaxTokens')}\n hint={t('field.continueTextMaxTokensHint')}\n {...shared}\n {...state.continueTextMaxTokens}\n onEdit={(text) => props.edit('continueTextMaxTokens', text)}\n placeholder={t('default.continueTextMaxTokens')}\n onReset={() => props.resetField('continueTextMaxTokens')}\n />\n </SettingsSection>\n\n <SettingsSection\n t={t}\n titleKey=\"section.safety.title\"\n descriptionKey=\"section.safety.description\"\n tone=\"safety\"\n >\n <BooleanField\n wide\n id=\"auto-continue-guard-tools\"\n label={t('field.guardTools')}\n hint={t('field.guardToolsHint')}\n {...shared}\n {...state.guardTools}\n onEdit={(text) => props.edit('guardTools', text)}\n onReset={() => props.resetField('guardTools')}\n />\n <ValueField\n wide\n id=\"auto-continue-guard-pending-text\"\n label={t('field.guardPendingText')}\n hint={t('field.guardPendingTextHint')}\n {...shared}\n {...state.guardPendingText}\n onEdit={(text) => props.edit('guardPendingText', text)}\n placeholder={t('default.guardPendingText')}\n onReset={() => props.resetField('guardPendingText')}\n />\n <ValueField\n wide\n id=\"auto-continue-guard-done-text\"\n label={t('field.guardDoneText')}\n hint={t('field.guardDoneTextHint')}\n {...shared}\n {...state.guardDoneText}\n onEdit={(text) => props.edit('guardDoneText', text)}\n placeholder={t('default.guardDoneText')}\n onReset={() => props.resetField('guardDoneText')}\n />\n <ValueField\n id=\"auto-continue-grace-ms\"\n label={t('field.graceMs')}\n hint={t('field.graceMsHint')}\n numeric\n {...shared}\n {...state.graceMs}\n onEdit={(text) => props.edit('graceMs', text)}\n onReset={() => props.resetField('graceMs')}\n />\n <ValueField\n id=\"auto-continue-cooldown-ms\"\n label={t('field.cooldownMs')}\n hint={t('field.cooldownMsHint')}\n numeric\n {...shared}\n {...state.cooldownMs}\n onEdit={(text) => props.edit('cooldownMs', text)}\n onReset={() => props.resetField('cooldownMs')}\n />\n <ValueField\n id=\"auto-continue-max-consecutive\"\n label={t('field.maxConsecutive')}\n hint={t('field.maxConsecutiveHint')}\n numeric\n {...shared}\n {...state.maxConsecutive}\n onEdit={(text) => props.edit('maxConsecutive', text)}\n onReset={() => props.resetField('maxConsecutive')}\n />\n </SettingsSection>\n\n <SettingsSection\n t={t}\n titleKey=\"section.recovery.title\"\n descriptionKey=\"section.recovery.description\"\n tone=\"recovery\"\n >\n <BooleanField\n id=\"auto-continue-scan-on-boot\"\n label={t('field.scanOnBoot')}\n hint={t('field.scanOnBootHint')}\n {...shared}\n {...state.scanOnBoot}\n onEdit={(text) => props.edit('scanOnBoot', text)}\n onReset={() => props.resetField('scanOnBoot')}\n />\n <BooleanField\n id=\"auto-continue-classify\"\n label={t('field.classify')}\n hint={t('field.classifyHint')}\n {...shared}\n {...state.classify}\n onEdit={(text) => props.edit('classify', text)}\n onReset={() => props.resetField('classify')}\n />\n <ValueField\n id=\"auto-continue-scan-limit\"\n label={t('field.scanLimit')}\n hint={t('field.scanLimitHint')}\n numeric\n {...shared}\n {...state.scanLimit}\n onEdit={(text) => props.edit('scanLimit', text)}\n onReset={() => props.resetField('scanLimit')}\n />\n <ValueField\n id=\"auto-continue-fresh-ms\"\n label={t('field.freshMs')}\n hint={t('field.freshMsHint')}\n numeric\n {...shared}\n {...state.freshMs}\n onEdit={(text) => props.edit('freshMs', text)}\n onReset={() => props.resetField('freshMs')}\n />\n <ValueField\n wide\n id=\"auto-continue-retryable-error-patterns\"\n label={t('field.retryableErrorPatterns')}\n hint={t('field.retryableErrorPatternsHint')}\n multiline\n {...shared}\n {...state.retryableErrorPatterns}\n onEdit={(text) => props.edit('retryableErrorPatterns', text)}\n placeholder={t('field.retryableErrorPatternsPlaceholder')}\n onReset={() => props.resetField('retryableErrorPatterns')}\n />\n <ValueField\n id=\"auto-continue-backoff-factor\"\n label={t('field.backoffFactor')}\n hint={t('field.backoffFactorHint')}\n numeric\n {...shared}\n {...state.backoffFactor}\n onEdit={(text) => props.edit('backoffFactor', text)}\n onReset={() => props.resetField('backoffFactor')}\n />\n <ValueField\n id=\"auto-continue-backoff-max\"\n label={t('field.backoffMaxMs')}\n hint={t('field.backoffMaxMsHint')}\n numeric\n {...shared}\n {...state.backoffMaxMs}\n onEdit={(text) => props.edit('backoffMaxMs', text)}\n onReset={() => props.resetField('backoffMaxMs')}\n />\n <BooleanField\n id=\"auto-continue-notify\"\n label={t('field.notify')}\n hint={t('field.notifyHint')}\n {...shared}\n {...state.notify}\n onEdit={(text) => props.edit('notify', text)}\n onReset={() => props.resetField('notify')}\n />\n <BooleanField\n id=\"auto-continue-verbose\"\n label={t('field.verbose')}\n hint={t('field.verboseHint')}\n {...shared}\n {...state.verbose}\n onEdit={(text) => props.edit('verbose', text)}\n onReset={() => props.resetField('verbose')}\n />\n </SettingsSection>\n\n <SettingsSection\n t={t}\n titleKey=\"section.loop.title\"\n descriptionKey=\"section.loop.description\"\n tone=\"loop\"\n >\n <BooleanField\n wide\n id=\"auto-continue-loop-guard\"\n label={t('field.loopGuard')}\n hint={t('field.loopGuardHint')}\n {...shared}\n {...state.loopGuard}\n onEdit={(text) => props.edit('loopGuard', text)}\n onReset={() => props.resetField('loopGuard')}\n />\n <ValueField\n id=\"auto-continue-loop-short-chars\"\n label={t('field.loopShortChars')}\n hint={t('field.loopShortCharsHint')}\n numeric\n {...shared}\n {...state.loopShortChars}\n onEdit={(text) => props.edit('loopShortChars', text)}\n onReset={() => props.resetField('loopShortChars')}\n />\n <ValueField\n id=\"auto-continue-loop-window-ms\"\n label={t('field.loopWindowMs')}\n hint={t('field.loopWindowMsHint')}\n numeric\n {...shared}\n {...state.loopWindowMs}\n onEdit={(text) => props.edit('loopWindowMs', text)}\n onReset={() => props.resetField('loopWindowMs')}\n />\n <ValueField\n id=\"auto-continue-loop-short-count\"\n label={t('field.loopShortCount')}\n hint={t('field.loopShortCountHint')}\n numeric\n {...shared}\n {...state.loopShortCount}\n onEdit={(text) => props.edit('loopShortCount', text)}\n onReset={() => props.resetField('loopShortCount')}\n />\n <ValueField\n id=\"auto-continue-loop-repeat-text\"\n label={t('field.loopRepeatText')}\n hint={t('field.loopRepeatTextHint')}\n numeric\n {...shared}\n {...state.loopRepeatText}\n onEdit={(text) => props.edit('loopRepeatText', text)}\n onReset={() => props.resetField('loopRepeatText')}\n />\n <ValueField\n id=\"auto-continue-loop-tool-repeat\"\n label={t('field.loopToolRepeat')}\n hint={t('field.loopToolRepeatHint')}\n numeric\n {...shared}\n {...state.loopToolRepeat}\n onEdit={(text) => props.edit('loopToolRepeat', text)}\n onReset={() => props.resetField('loopToolRepeat')}\n />\n <ValueField\n wide\n id=\"auto-continue-loop-text\"\n label={t('field.loopText')}\n hint={t('field.loopTextHint')}\n {...shared}\n {...state.loopText}\n onEdit={(text) => props.edit('loopText', text)}\n placeholder={t('default.loopText')}\n onReset={() => props.resetField('loopText')}\n />\n </SettingsSection>\n\n <SettingsSection\n t={t}\n titleKey=\"section.live.title\"\n descriptionKey=\"section.live.description\"\n tone=\"live\"\n >\n <LivePanels t={t} />\n </SettingsSection>\n </div>\n </SettingsCard>\n );\n}\n", "/**\n * Snapshot-store bridge across the two public DSH client module layouts.\n *\n * DSH 0.1.2 moved the store engine from the dynamic\n * `@deepseek-ai/dsh-client-runtime/client` row into the shell-seeded\n * `@deepseek-ai/dsh-client-store` platform module. Keep the probe dynamic so\n * esbuild does not turn both candidates into eager top-level requires: the\n * loader must only resolve the module that exists in the running DSH cohort.\n */\n\n/** Writable observable snapshot used by the settings card. */\nexport interface SnapshotStore<T> {\n getSnapshot(): T;\n subscribe(listener: () => void): () => void;\n update(mutator: (draft: T) => void): void;\n set(next: T): void;\n}\n\n/** Settings state consumed by the staged form. */\nexport interface SettingsScopeSnapshot<T> {\n status: 'loading' | 'ready' | 'unavailable';\n value: T | undefined;\n base: unknown;\n user: unknown;\n revision: number | undefined;\n writable: boolean;\n mode: 'host' | 'memory';\n}\n\n/** Stable subset shared by the legacy and DSH 0.1.2 settings scopes. */\nexport interface SettingsScope<T> {\n getSnapshot(): SettingsScopeSnapshot<T>;\n subscribe(listener: () => void): () => void;\n set(field: string, value: unknown): Promise<void>;\n unset(field: string): Promise<void>;\n}\n\ninterface SnapshotStoreModule {\n createSnapshotStore<T>(\n init: T,\n options?: { flush?: 'raf' | 'sync'; persist?: { name: string } },\n ): SnapshotStore<T>;\n}\n\nfunction resolveSnapshotStore(): SnapshotStoreModule {\n // String assembly is intentional: it preserves the lazy try/fallback in the\n // emitted client bundle instead of letting the bundler resolve both names.\n const current = ['@deepseek-ai/dsh-client', '-store'].join('');\n const legacy = ['@deepseek-ai/dsh-client-runtime', '/client'].join('');\n try {\n return require(current) as SnapshotStoreModule;\n } catch {\n return require(legacy) as SnapshotStoreModule;\n }\n}\n\nexport const { createSnapshotStore } = resolveSnapshotStore();\n", "/**\n * Host status bridge, browser side.\n *\n * Subscribes to the host engine's `/api/auto-continue-bridge` SSE stream:\n * notifications (shown via the browser Notification API, action buttons POST\n * to `/api/auto-continue-action`) and runtime state (today's stats and the\n * paused-sessions list) consumed by the settings card's live panels.\n */\n\n/** 今日统计视图(与 host 引擎的 DayStats 对应)。 */\nexport interface DayStatsView {\n date: string;\n sent: number;\n skipped: number;\n recovered: number;\n failed: number;\n gaveUp: number;\n looped: number;\n byCode: Record<string, number>;\n}\n\n/** 已暂停会话视图。 */\nexport interface PausedSessionView {\n sessionId: string;\n until: number;\n}\n\ninterface BridgeState {\n stats: DayStatsView;\n paused: PausedSessionView[];\n}\n\ninterface BridgeNotice {\n id: string;\n title: string;\n body: string;\n sessionId?: string;\n actions: { action: string; title: string }[];\n at: number;\n}\n\nconst EMPTY_STATS: DayStatsView = {\n date: '',\n sent: 0,\n skipped: 0,\n recovered: 0,\n failed: 0,\n gaveUp: 0,\n looped: 0,\n byCode: {},\n};\n\nlet state: BridgeState = { stats: EMPTY_STATS, paused: [] };\nconst listeners = new Set<() => void>();\n\n/** 当前桥状态里的已暂停会话(卡片面板用)。 */\nexport function pausedSessions(): PausedSessionView[] {\n return state.paused;\n}\n\n/** 当前桥状态里的今日统计(卡片面板用)。 */\nexport function readTodayStats(): DayStatsView {\n return state.stats;\n}\n\n/** 清零今日统计(经动作端点交给 host 引擎执行)。 */\nexport function resetTodayStats(): void {\n void postAction({ action: 'reset-stats' });\n}\n\n/** 解除某个会话的暂停(经动作端点交给 host 引擎执行)。 */\nexport function unpauseSession(sessionId: string): void {\n void postAction({ action: 'unpause', sessionId });\n}\n\n/** 订阅桥状态变化(卡片面板刷新用)。 */\nexport function subscribeBridge(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/** 通知按钮动作回传 host(立即续跑 / 暂停该会话 1 小时 / 解除暂停 / 清零统计)。 */\nasync function postAction(payload: { action: string; sessionId?: string }): Promise<void> {\n try {\n await fetch('/api/auto-continue-action', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n });\n } catch {\n /* host 不可达时静默 */\n }\n}\n\nfunction handleEvent(event: { type: string; notice?: BridgeNotice; stats?: DayStatsView; paused?: PausedSessionView[] }): void {\n if (event.type === 'state') {\n state = {\n stats: event.stats ?? EMPTY_STATS,\n paused: event.paused ?? [],\n };\n for (const listener of listeners) listener();\n } else if (event.type === 'notice' && event.notice !== undefined) {\n showNotification(event.notice);\n }\n}\n\n/** 浏览器通知: 展示 host 通知并挂动作按钮。 */\nfunction showNotification(notice: BridgeNotice): void {\n try {\n const N = (globalThis as { Notification?: unknown }).Notification as\n | (new (t: string, o: { body: string; actions?: { action: string; title: string }[] }) => unknown)\n | undefined;\n if (typeof N === 'undefined') return;\n const permission = (N as unknown as { permission?: string }).permission;\n const create = (): void => {\n const instance = new N(notice.title, {\n body: notice.body,\n ...(notice.actions.length > 0 ? { actions: notice.actions } : {}),\n });\n const target = instance as {\n onclick?: (() => void) | null;\n onaction?: ((event: { action: string }) => void) | null;\n };\n target.onclick = () => {\n try {\n (globalThis as { focus?: () => void }).focus?.();\n } catch {\n /* ignore */\n }\n };\n target.onaction = (event) => {\n if (notice.sessionId !== undefined) {\n void postAction({ action: event.action, sessionId: notice.sessionId });\n }\n };\n };\n if (permission === 'granted') {\n create();\n } else if (permission === 'default') {\n void (N as unknown as { requestPermission?: () => Promise<string> }).requestPermission?.()\n .then((result) => {\n if (result === 'granted') create();\n })\n .catch(() => {});\n }\n } catch {\n /* 通知失败不影响核心逻辑 */\n }\n}\n\n/**\n * 启动桥订阅(带断线重连), 返回停止函数。\n * 由 client apply 的 ctx.effect 持有。\n */\nexport function startBridge(): () => void {\n let stopped = false;\n let controller: AbortController | undefined;\n\n const loop = async (): Promise<void> => {\n while (!stopped) {\n controller = new AbortController();\n try {\n const response = await fetch('/api/auto-continue-bridge', { signal: controller.signal });\n if (!response.ok || response.body === null) throw new Error(`bridge HTTP ${response.status}`);\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n let idx = buffer.indexOf('\\n\\n');\n while (idx !== -1) {\n const chunk = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n for (const line of chunk.split('\\n')) {\n if (line.startsWith('data: ')) {\n try {\n handleEvent(JSON.parse(line.slice(6)) as Parameters<typeof handleEvent>[0]);\n } catch {\n /* 忽略坏帧 */\n }\n }\n }\n idx = buffer.indexOf('\\n\\n');\n }\n }\n } catch {\n /* 断线: 退避重连 */\n }\n if (!stopped) await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n };\n void loop();\n\n return () => {\n stopped = true;\n controller?.abort();\n };\n}\n", "/**\n * Staged form model behind the plugin settings card — a self-contained\n * implementation of the plugin-card store pattern used by the DSH plugin\n * configuration section.\n *\n * A card stages what the user types and writes it only when they save. Each\n * settings write is a durable, revision-fenced document mutation, so staging\n * keeps what is on screen exactly what a save would store. A field shows its\n * effective value — the user layer over the composition layer over the schema\n * default — and whether the user layer carries it (presence, not value\n * equality, marks an override).\n */\nimport type { SettingsScope, SnapshotStore } from './dsh-store-compat.ts';\n\n/** The write one field's staged text performs when the card is saved. */\nexport type FieldWrite = { kind: 'set'; value: unknown } | { kind: 'clear' };\n\n/** How one field converts between its stored value and its draft text. */\nexport interface CardFieldSpec {\n /** Field name inside the namespace section. */\n field: string;\n /** Render a stored value as draft text; the empty string when the section carries none. */\n format: (value: unknown) => string;\n /**\n * The write this draft text stages, or undefined when the text is not a\n * value this field accepts — which blocks the save rather than discarding it.\n */\n parse: (text: string) => FieldWrite | undefined;\n}\n\n/** One field as the card's control renders it. */\nexport interface CardFieldState {\n /** Draft text the control renders. */\n text: string;\n /** Whether saving would leave a user-layer entry for this field. */\n overridden: boolean;\n /** Whether the draft is not a value this field accepts, which blocks saving. */\n invalid: boolean;\n}\n\n/** Form state every plugin card shares. */\nexport interface CardShell {\n /** False while the namespace is not served to this client; the card renders nothing. */\n available: boolean;\n /** Whether the Host document accepts writes. */\n writable: boolean;\n /** Whether the form holds edits that a save would write. */\n dirty: boolean;\n /** Whether any staged draft is invalid, which blocks the save. */\n invalid: boolean;\n /** Whether a save is crossing the wire. */\n saving: boolean;\n /** Whether the last save did not land as staged; cleared by the next edit or save. */\n failed: boolean;\n}\n\n/** The write actions the 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 saving lets the field re-inherit 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\n/** A whole-number field. An empty draft clears the field; a non-number or out-of-range draft blocks the save. */\nexport function numberField(field: string, min = 0): 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 if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed < min) return undefined;\n return { kind: 'set', value: parsed };\n },\n };\n}\n\n/** A free-text field. An empty draft clears the field, so emptying the control and saving is the same gesture as resetting it. */\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/** A boolean field, edited through true/false draft text; an empty draft inherits. */\nexport function booleanField(field: string): CardFieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim();\n if (trimmed === '') return { kind: 'clear' };\n if (trimmed === 'true') return { kind: 'set', value: true };\n if (trimmed === 'false') return { kind: 'set', value: false };\n return undefined;\n },\n };\n}\n\n/** One field's staged edit. */\ninterface StagedEdit {\n /** Draft text the control renders. */\n text: string;\n /** True when this edit clears the field whatever text it shows. */\n clear: boolean;\n}\n\n/**\n * Stages one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted, so the\n * outcome is read back from the section rather than predicted here. A save\n * that did not land keeps its drafts, so the user can correct them instead of\n * retyping.\n */\nexport class CardForm<T> {\n private readonly specs: Map<string, CardFieldSpec>;\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 - the bound settings scope for this card's namespace.\n * @param specs - the section fields this card edits.\n */\n constructor(\n private readonly scope: SettingsScope<T>,\n specs: CardFieldSpec[],\n ) {\n this.specs = new Map(specs.map((spec) => [spec.field, spec]));\n this.scope.subscribe(() => this.publish());\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<S>(project: () => S, createStore: (init: S) => SnapshotStore<S>): SnapshotStore<S> {\n const store = createStore(project());\n this.listeners.add(() => store.set(project()));\n return store;\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot();\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: this.plan().length > 0,\n invalid: this.plan().some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n };\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): CardFieldState {\n const spec = this.specOf(field);\n const staged = this.staged.get(field);\n if (staged === undefined) {\n return {\n text: spec.format(this.sectionValue(field)),\n overridden: this.stored(field),\n invalid: false,\n };\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 /** The actions the card's slot registration injects. */\n actions(): CardActions {\n return {\n edit: (field, text) => this.stage(field, { text, clear: false }),\n resetField: (field) => {\n this.stage(field, { text: this.specOf(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 /**\n * Write every staged edit, then re-seed from what the Host accepted.\n * @returns settlement after every write and the read-back.\n */\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 // Snapshot the fields this save writes, so edits staged while it is in\n // flight survive: only the staged keys this save actually wrote are cleared.\n const fields = new Set(plan.map((item) => item.field));\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) {\n for (const field of fields) this.staged.delete(field);\n }\n this.saving = false;\n this.failed = !landed;\n this.publish();\n }\n\n /**\n * Every staged edit a save would write. An entry whose draft is not a value\n * its field accepts carries no write: the form is still dirty, and the save\n * refuses rather than dropping the edit. A staged edit that matches the\n * effective section is not a write at all.\n */\n private plan(): { field: string; run: (() => Promise<boolean>) | undefined }[] {\n const plan: { field: string; run: (() => Promise<boolean>) | undefined }[] = [];\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(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 }\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 specOf(field: string): CardFieldSpec {\n const spec = this.specs.get(field);\n if (spec === undefined) throw new Error(`settings card has no field ${field}`);\n return spec;\n }\n\n private sectionValue(field: string): unknown {\n return (this.scope.getSnapshot().value as Record<string, unknown> | undefined)?.[field];\n }\n\n private baseValue(field: string): unknown {\n return (this.scope.getSnapshot().base as Record<string, unknown> | undefined)?.[field];\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.scope.getSnapshot().user as Record<string, unknown> | undefined;\n }\n\n private stored(field: string): boolean {\n const user = this.userLayer();\n return user !== undefined && Object.prototype.hasOwnProperty.call(user, field);\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener();\n }\n}\n", "/**\n * Styles for the auto-continue settings card, injected at factory\n * materialization so the client module system's style bookkeeping (HMR) owns\n * them. Uses the DSH design tokens (`--dsw-alias-*`) so the card follows the\n * active theme.\n */\n\nconst css = `\n.dshAcCard {\n --dsh-ac-violet: #8b7cff;\n --dsh-ac-cyan: #45cce5;\n --dsh-ac-mint: #46d69d;\n --dsh-ac-amber: #f1b95c;\n isolation: isolate;\n position: relative;\n overflow: hidden;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n border-radius: 16px;\n list-style: none;\n box-shadow: 0 10px 34px rgb(0 0 0 / 8%);\n transition: border-color .2s ease, background .2s ease, box-shadow .2s ease, transform .2s ease;\n}\n.dshAcCard::before {\n content: \"\";\n z-index: 2;\n position: absolute;\n inset: 0 0 auto;\n height: 2px;\n pointer-events: none;\n opacity: .72;\n background: linear-gradient(90deg, transparent 1%, var(--dsh-ac-violet) 22%, var(--dsh-ac-cyan) 52%, var(--dsh-ac-mint) 80%, transparent 99%);\n}\n.dshAcCard::after {\n content: \"\";\n z-index: -1;\n position: absolute;\n width: 190px;\n height: 190px;\n top: -104px;\n left: -76px;\n pointer-events: none;\n border-radius: 999px;\n background: radial-gradient(circle, rgb(139 124 255 / 14%) 0, transparent 68%);\n}\n.dshAcCard:hover {\n border-color: color-mix(in srgb, var(--dsh-ac-violet) 48%, var(--dsw-alias-border-l2));\n box-shadow: 0 14px 42px rgb(0 0 0 / 12%);\n transform: translateY(-1px);\n}\n.dshAcCardOpen {\n background: var(--dsw-alias-bg-layer-2);\n border-color: color-mix(in srgb, var(--dsh-ac-violet) 42%, var(--dsw-alias-border-l2));\n box-shadow: 0 18px 54px rgb(0 0 0 / 14%);\n transform: none;\n}\n.dshAcHeaderFrame {\n align-items: stretch;\n flex-direction: column;\n display: flex;\n}\n.dshAcHeader {\n appearance: none;\n min-width: 0;\n flex: 1;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n background: none;\n border: 0;\n border-radius: 16px;\n align-items: center;\n gap: 14px;\n padding: 18px 18px 12px;\n display: flex;\n}\n.dshAcHeader:focus-visible { outline: 2px solid var(--dsh-ac-violet); outline-offset: -3px; }\n.dshAcRelayMark {\n width: 54px;\n height: 54px;\n flex: none;\n place-items: center;\n display: grid;\n color: var(--dsh-ac-cyan);\n border: 1px solid color-mix(in srgb, var(--dsh-ac-violet) 42%, var(--dsw-alias-border-l2));\n border-radius: 17px;\n background: color-mix(in srgb, var(--dsw-alias-bg-layer-2) 84%, var(--dsh-ac-violet) 16%);\n box-shadow: inset 0 0 0 1px rgb(255 255 255 / 4%), 0 8px 24px rgb(62 51 153 / 16%);\n}\n.dshAcRelayMark svg { width: 44px; height: 44px; overflow: visible; }\n.dshAcRelayArc { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }\n.dshAcRelayArcEcho { opacity: .42; }\n.dshAcRelayNode { stroke: var(--dsw-alias-bg-layer-3); stroke-width: 1.5; }\n.dshAcRelayNodeStart { fill: var(--dsh-ac-amber); }\n.dshAcRelayNodeEnd { fill: var(--dsh-ac-mint); }\n.dshAcRelayPulse { fill: var(--dsh-ac-violet); opacity: .85; }\n.dshAcCard:hover .dshAcRelayPulse, .dshAcCardOpen .dshAcRelayPulse {\n animation: dshAcRelayTravel 1.8s cubic-bezier(.4, 0, .2, 1) infinite;\n}\n.dshAcHeadText { flex-direction: column; flex: 1; gap: 3px; min-width: 0; display: flex; }\n.dshAcEyebrow {\n color: color-mix(in srgb, var(--dsh-ac-violet) 76%, var(--dsw-alias-label-secondary));\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 10px;\n font-weight: 700;\n line-height: 1.4;\n letter-spacing: .12em;\n text-transform: uppercase;\n}\n.dshAcName {\n color: var(--dsw-alias-label-primary);\n font-family: ui-rounded, \"SF Pro Rounded\", \"Segoe UI\", sans-serif;\n font-size: 18px;\n font-weight: 680;\n letter-spacing: -.015em;\n line-height: 1.35;\n}\n.dshAcDescription { max-width: 660px; color: var(--dsw-alias-label-tertiary); font-size: 13px; line-height: 1.5; }\n.dshAcJourney { flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 4px; display: flex; }\n.dshAcJourneyStep {\n align-items: center;\n gap: 5px;\n color: var(--dsw-alias-label-secondary);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 10px;\n font-weight: 600;\n line-height: 1.4;\n letter-spacing: .02em;\n display: inline-flex;\n}\n.dshAcJourneyDot { width: 5px; height: 5px; flex: none; border-radius: 999px; background: currentColor; box-shadow: 0 0 0 3px rgb(255 255 255 / 3%); }\n.dshAcJourneyInterrupted .dshAcJourneyDot { color: var(--dsh-ac-amber); }\n.dshAcJourneyGrace .dshAcJourneyDot { color: var(--dsh-ac-cyan); }\n.dshAcJourneyContinue .dshAcJourneyDot { color: var(--dsh-ac-mint); }\n.dshAcJourneyLine {\n width: 25px;\n height: 1px;\n flex: none;\n opacity: .7;\n background: linear-gradient(90deg, var(--dsh-ac-violet), var(--dsh-ac-cyan), var(--dsh-ac-mint));\n background-size: 220% 100%;\n}\n.dshAcCard:hover .dshAcJourneyLine, .dshAcCardOpen .dshAcJourneyLine { animation: dshAcSignalSweep 1.8s linear infinite; }\n.dshAcChevron {\n width: 30px;\n height: 30px;\n color: var(--dsw-alias-label-tertiary);\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 999px;\n flex: none;\n place-items: center;\n display: grid;\n transition: color .18s ease, border-color .18s ease, transform .18s ease;\n}\n.dshAcChevron svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }\n.dshAcHeader:hover .dshAcChevron { color: var(--dsh-ac-violet); border-color: color-mix(in srgb, var(--dsh-ac-violet) 48%, var(--dsw-alias-border-l2)); }\n.dshAcChevronOpen { transform: rotate(180deg); }\n.dshAcGithub {\n min-width: 0;\n max-width: none;\n align-self: stretch;\n align-items: center;\n gap: 10px;\n margin: 0 18px 16px;\n padding: 9px 11px;\n color: var(--dsw-alias-label-primary);\n text-decoration: none;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 13px;\n background: color-mix(in srgb, var(--dsw-alias-bg-layer-2) 90%, var(--dsh-ac-violet) 10%);\n display: flex;\n transition: border-color .18s ease, background .18s ease, transform .18s ease;\n}\n.dshAcGithub:hover {\n border-color: color-mix(in srgb, var(--dsh-ac-violet) 58%, var(--dsw-alias-border-l2));\n background: color-mix(in srgb, var(--dsw-alias-bg-layer-2) 82%, var(--dsh-ac-violet) 18%);\n transform: translateY(-1px);\n}\n.dshAcGithub:focus-visible { outline: 2px solid var(--dsh-ac-violet); outline-offset: 2px; }\n.dshAcGithubIcon { width: 23px; height: 23px; flex: none; color: var(--dsw-alias-label-primary); }\n.dshAcGithubIcon svg { width: 100%; height: 100%; fill: currentColor; }\n.dshAcGithubText { min-width: 0; flex: 1; flex-direction: column; gap: 1px; display: flex; }\n.dshAcGithubAction { font-size: 12px; font-weight: 680; line-height: 1.4; }\n.dshAcGithubAction::before { content: \"★\"; color: var(--dsh-ac-amber); margin-right: 5px; }\n.dshAcGithubSlug {\n overflow: hidden;\n color: var(--dsw-alias-label-tertiary);\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 9.5px;\n line-height: 1.4;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.dshAcExternal { width: 15px; height: 15px; flex: none; color: var(--dsw-alias-label-tertiary); }\n.dshAcExternal svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; }\n.dshAcBody { border-top: 1px solid var(--dsw-alias-border-l2); margin: 0 18px 12px; padding: 4px 0 0; }\n.dshAcReadOnly { color: var(--dsw-alias-label-tertiary); margin: 12px 0 0; font-size: 12px; line-height: 1.5; }\n.dshAcPending {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n flex: none;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcFooter {\n border-top: 1px solid var(--dsw-alias-border-l2);\n justify-content: flex-end;\n align-items: center;\n gap: 8px;\n padding: 12px 0 4px;\n display: flex;\n}\n.dshAcFailed { min-width: 0; color: var(--dsw-alias-label-error); flex: 1; margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcDiscard, .dshAcSave {\n appearance: none;\n font: inherit;\n cursor: pointer;\n border: 1px solid transparent;\n border-radius: 8px;\n padding: 5px 14px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcDiscard { border-color: var(--dsw-alias-border-l2); color: var(--dsw-alias-label-secondary); background: none; }\n.dshAcDiscard:hover:not(:disabled) { color: var(--dsw-alias-label-primary); border-color: var(--dsw-alias-label-dimmed); }\n.dshAcSave { background: var(--dsw-alias-label-primary); color: var(--dsw-alias-bg-layer-3); }\n.dshAcDiscard:disabled, .dshAcSave:disabled { opacity: .4; cursor: default; }\n.dshAcDiscard:focus-visible, .dshAcSave:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 1px; }\n.dshAcFormCanvas { flex-direction: column; gap: 14px; padding: 12px 0 8px; display: flex; }\n.dshAcFormSection {\n --dsh-ac-section: var(--dsh-ac-violet);\n overflow: hidden;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 14px;\n background: var(--dsw-alias-bg-layer-3);\n background: color-mix(in srgb, var(--dsw-alias-bg-layer-3) 95%, var(--dsh-ac-section) 5%);\n}\n.dshAcFormSection-handoff { --dsh-ac-section: var(--dsh-ac-mint); }\n.dshAcFormSection-safety { --dsh-ac-section: var(--dsh-ac-amber); }\n.dshAcFormSection-recovery { --dsh-ac-section: var(--dsh-ac-cyan); }\n.dshAcFormSection-loop { --dsh-ac-section: var(--dsh-ac-violet); }\n.dshAcFormSection-live { --dsh-ac-section: color-mix(in srgb, var(--dsh-ac-violet) 60%, var(--dsh-ac-cyan)); }\n.dshAcSectionHead {\n align-items: center;\n gap: 11px;\n padding: 13px 14px 11px;\n border-bottom: 1px solid var(--dsw-alias-border-l2);\n display: flex;\n}\n.dshAcSectionSignal {\n width: 4px;\n height: 34px;\n flex: none;\n border-radius: 999px;\n background: var(--dsh-ac-section);\n box-shadow: 0 0 18px color-mix(in srgb, var(--dsh-ac-section) 55%, transparent);\n}\n.dshAcSectionCopy { min-width: 0; flex-direction: column; gap: 2px; display: flex; }\n.dshAcSectionTitle {\n color: var(--dsw-alias-label-primary);\n font-family: ui-rounded, \"SF Pro Rounded\", \"Segoe UI\", sans-serif;\n font-size: 14px;\n font-weight: 680;\n line-height: 1.4;\n}\n.dshAcSectionDescription { color: var(--dsw-alias-label-tertiary); font-size: 11.5px; line-height: 1.45; }\n.dshAcSectionGrid {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n column-gap: 22px;\n padding: 0 14px 4px;\n display: grid;\n}\n.dshAcField { min-width: 0; flex-direction: column; gap: 6px; padding: 12px 0; border-top: 1px solid var(--dsw-alias-border-l2); display: flex; }\n.dshAcSectionGrid > .dshAcField:first-child { border-top: 0; }\n.dshAcFieldWide { grid-column: 1 / -1; }\n.dshAcHead { align-items: center; gap: 8px; display: flex; }\n.dshAcLabel { min-width: 0; color: var(--dsw-alias-label-primary); flex: 1; font-size: 13px; font-weight: 500; line-height: 1.5; }\n.dshAcBadges { align-items: center; gap: 8px; display: inline-flex; }\n.dshAcBadge {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcReset {\n font: inherit;\n color: var(--dsw-alias-label-secondary);\n cursor: pointer;\n background: none;\n border: none;\n padding: 0;\n font-size: 12px;\n line-height: 1.5;\n}\n.dshAcReset:hover:not(:disabled) { color: var(--dsw-alias-label-primary); }\n.dshAcReset:disabled { cursor: default; }\n.dshAcInput {\n box-sizing: border-box;\n width: 100%;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n height: 34px;\n font: inherit;\n color: var(--dsw-alias-label-primary);\n border-radius: 8px;\n padding: 0 12px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcInput:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }\n.dshAcInput:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.dshAcInputInvalid { border-color: var(--dsw-alias-label-error); }\n.dshAcTextArea { box-sizing: border-box; height: auto; min-height: 84px; padding: 8px 12px; resize: vertical; }\n.dshAcSelect {\n box-sizing: border-box;\n width: 100%;\n border: 1px solid var(--dsw-alias-border-l2);\n background: var(--dsw-alias-bg-layer-3);\n height: 34px;\n font: inherit;\n color: var(--dsw-alias-label-primary);\n border-radius: 8px;\n padding: 0 8px;\n font-size: 13px;\n line-height: 1.5;\n}\n.dshAcSelect:focus-visible { border-color: var(--dsw-alias-brand-primary); outline: none; }\n.dshAcSelect:disabled { color: var(--dsw-alias-label-tertiary); cursor: default; }\n.dshAcInvalid { color: var(--dsw-alias-label-error); margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcHint { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 1.5; }\n.dshAcPanel { min-width: 0; flex-direction: column; gap: 8px; padding: 12px 0 14px; display: flex; }\n.dshAcPanel + .dshAcPanel { border-left: 1px solid var(--dsw-alias-border-l2); padding-left: 20px; }\n.dshAcPanelHead { align-items: center; gap: 8px; display: flex; }\n.dshAcPanelTitle { color: var(--dsw-alias-label-primary); flex: 1; font-size: 13px; font-weight: 600; line-height: 1.5; }\n.dshAcStats { gap: 4px 16px; margin: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); display: grid; }\n.dshAcStats > div { justify-content: space-between; gap: 8px; display: flex; }\n.dshAcStats dt { color: var(--dsw-alias-label-secondary); font-size: 12px; line-height: 1.5; }\n.dshAcStats dd { color: var(--dsw-alias-label-primary); margin: 0; font-size: 12px; font-weight: 600; line-height: 1.5; }\n.dshAcCodes { flex-wrap: wrap; align-items: center; gap: 6px; display: flex; }\n.dshAcCode {\n white-space: nowrap;\n background: var(--dsw-alias-bg-module-platform);\n color: var(--dsw-alias-label-secondary);\n border-radius: 999px;\n padding: 1px 8px;\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n.dshAcPauseList { flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; display: flex; }\n.dshAcPauseList li { align-items: center; gap: 8px; display: flex; }\n.dshAcPauseId {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n color: var(--dsw-alias-label-primary);\n font-size: 12px;\n line-height: 1.5;\n}\n@keyframes dshAcRelayTravel {\n 0% { opacity: 0; transform: translate(-19px, 18px) scale(.7); }\n 18% { opacity: 1; }\n 82% { opacity: 1; }\n 100% { opacity: 0; transform: translate(12px, 6px) scale(1.15); }\n}\n@keyframes dshAcSignalSweep {\n from { background-position: 100% 0; }\n to { background-position: -120% 0; }\n}\n@media (max-width: 820px) {\n .dshAcSectionGrid { grid-template-columns: minmax(0, 1fr); }\n .dshAcFieldWide { grid-column: auto; }\n .dshAcPanel + .dshAcPanel {\n border-top: 1px solid var(--dsw-alias-border-l2);\n border-left: 0;\n padding-left: 0;\n }\n}\n@media (max-width: 560px) {\n .dshAcHeader { align-items: flex-start; gap: 11px; padding: 15px 13px 10px; }\n .dshAcRelayMark { width: 46px; height: 46px; border-radius: 14px; }\n .dshAcRelayMark svg { width: 38px; height: 38px; }\n .dshAcName { font-size: 16px; }\n .dshAcDescription { font-size: 12px; }\n .dshAcJourney { gap: 5px; }\n .dshAcJourneyLine { width: 13px; }\n .dshAcChevron { width: 27px; height: 27px; }\n .dshAcPending { display: none; }\n .dshAcGithub { margin: 0 13px 13px; }\n .dshAcBody { margin-right: 13px; margin-left: 13px; }\n}\n@media (prefers-reduced-motion: reduce) {\n .dshAcCard, .dshAcGithub, .dshAcChevron { transition: none; }\n .dshAcCard:hover, .dshAcGithub:hover { transform: none; }\n .dshAcRelayPulse, .dshAcJourneyLine { animation: none !important; }\n}\n`;\n\n/** Inject the stylesheet once; a no-op outside a browser environment. */\nexport function injectStyles(): void {\n if (typeof document === 'undefined') return;\n if (document.querySelector('style[data-plugin-css=\"auto-continue/card\"]') !== null) return;\n const tag = document.createElement('style');\n tag.dataset.plugin = 'dsh-client-auto-continue';\n tag.dataset.pluginCss = 'auto-continue/card';\n tag.textContent = css;\n document.head.appendChild(tag);\n}\n"],
|
|
5
|
+
"mappings": "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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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",
|
|
6
6
|
"names": ["state"]
|
|
7
7
|
}
|