@mikedown/core 0.2.0 → 0.3.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/CHANGELOG.md +8 -0
- package/README.md +121 -2
- package/dist/ai/engines-page.d.ts +130 -0
- package/dist/ai/engines-page.js +10 -0
- package/dist/ai/engines-page.js.map +1 -0
- package/dist/ai/index.d.ts +1531 -0
- package/dist/ai/index.js +395 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai-ui-C7ENTWWU.js +3370 -0
- package/dist/ai-ui-C7ENTWWU.js.map +1 -0
- package/dist/chunk-7A5HEPLK.js +4910 -0
- package/dist/chunk-7A5HEPLK.js.map +1 -0
- package/dist/chunk-GWCRPPCX.js +18 -0
- package/dist/chunk-GWCRPPCX.js.map +1 -0
- package/dist/chunk-JZWKEBCI.js +3899 -0
- package/dist/chunk-JZWKEBCI.js.map +1 -0
- package/dist/chunk-L4FO63DF.js +113 -0
- package/dist/chunk-L4FO63DF.js.map +1 -0
- package/dist/chunk-LXZG7IKN.js +39 -0
- package/dist/chunk-LXZG7IKN.js.map +1 -0
- package/dist/chunk-QDVY7WW6.js +165 -0
- package/dist/chunk-QDVY7WW6.js.map +1 -0
- package/dist/chunk-QWKT57TR.js +62 -0
- package/dist/chunk-QWKT57TR.js.map +1 -0
- package/dist/chunk-TSP7BAV3.js +22 -0
- package/dist/chunk-TSP7BAV3.js.map +1 -0
- package/dist/index.d.ts +19 -463
- package/dist/index.js +6511 -1258
- package/dist/index.js.map +1 -1
- package/dist/schema-DYzxkuSb.d.ts +46 -0
- package/dist/shared/anchoring.js +4 -16
- package/dist/shared/anchoring.js.map +1 -1
- package/dist/shared/imagePaste.js +3 -57
- package/dist/shared/imagePaste.js.map +1 -1
- package/dist/shared/sha1.js +3 -57
- package/dist/shared/sha1.js.map +1 -1
- package/dist/shared/wordCount.js +4 -12
- package/dist/shared/wordCount.js.map +1 -1
- package/dist/styles.css +3642 -127
- package/dist/types-CgEeIUhi.d.ts +432 -0
- package/dist/types-CsVNVSNY.d.ts +597 -0
- package/package.json +11 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ai-prefs.ts","../src/ai-settings.ts","../src/ai-toolbar.ts","../src/ai-request.ts","../src/ai-rewrite.ts","../src/ai-markdown-preview.ts"],"sourcesContent":["/**\n * Remembered AI choices (D10): the recent translate languages, the last\n * reading level and the thinking level. `localStorage` behind try/catch,\n * like the emoji picker's recents; storage may be missing or throw in a\n * webview sandbox, so every read has a default and every write is best\n * effort. Never a `mikedown.*` setting (D3).\n *\n * The thinking level is one value, set from the AI menu's Thinking row or\n * the popover's dial, and sent with every request until changed (null is\n * \"Default\": MikeDown picks per task, see `resolveThinkingLevel`). A kind that cannot express\n * it gets its nearest level (`thinkingLevelFor`).\n */\n\nimport { getAiAudience, type AiAudience } from './ai/prompts/rewrite';\nimport { nearestThinkingLevel, type AiThinkingLevel } from './ai/thinking';\n\nconst LANGUAGES_KEY = 'mikedown.ai.recentLanguages';\nconst AUDIENCE_KEY = 'mikedown.ai.audience';\nconst THINKING_KEY = 'mikedown.ai.thinking';\n\n/** Recent languages shown above the fixed list. */\nexport const MAX_RECENT_LANGUAGES = 3;\n\n/** Longest language name kept (it is free text from \"Other…\"). */\nconst LANGUAGE_MAX_CHARS = 60;\n\n/** The fixed translate list, in menu order (D17). */\nexport const AI_TRANSLATE_LANGUAGES: readonly string[] = [\n 'English', 'Spanish', 'French', 'German', 'Portuguese', 'Italian',\n 'Dutch', 'Japanese', 'Chinese (Simplified)', 'Korean', 'Arabic', 'Hindi',\n];\n\nconst sameLanguage = (a: string, b: string): boolean => a.toLocaleLowerCase() === b.toLocaleLowerCase();\n\n/** A typed language name, trimmed to one line; empty when there is nothing to keep. */\nfunction cleanLanguage(language: string): string {\n return language.replace(/\\s+/g, ' ').trim().slice(0, LANGUAGE_MAX_CHARS);\n}\n\n/** The recent languages, newest first, at most `MAX_RECENT_LANGUAGES`. */\nexport function loadRecentLanguages(): string[] {\n try {\n const raw = localStorage.getItem(LANGUAGES_KEY);\n if (!raw) {return [];}\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) {return [];}\n const out: string[] = [];\n for (const item of parsed) {\n if (typeof item !== 'string') {continue;}\n const lang = cleanLanguage(item);\n if (lang && !out.some((l) => sameLanguage(l, lang))) {out.push(lang);}\n if (out.length >= MAX_RECENT_LANGUAGES) {break;}\n }\n return out;\n } catch {\n return [];\n }\n}\n\n/** Put a language at the top of the recents, stored as typed. */\nexport function rememberLanguage(language: string): void {\n const lang = cleanLanguage(language);\n if (!lang) {return;}\n try {\n const next = [lang, ...loadRecentLanguages().filter((l) => !sameLanguage(l, lang))].slice(0, MAX_RECENT_LANGUAGES);\n localStorage.setItem(LANGUAGES_KEY, JSON.stringify(next));\n } catch {\n // Storage refused (sandboxed webview, private mode): the choice is not remembered.\n }\n}\n\n/** The language picker's rows: recents first, then the fixed list without them. */\nexport function translateLanguageChoices(recents: string[] = loadRecentLanguages()): { recents: string[]; languages: string[] } {\n return {\n recents,\n languages: AI_TRANSLATE_LANGUAGES.filter((l) => !recents.some((r) => sameLanguage(r, l))),\n };\n}\n\n/** The last reading level chosen, or null. */\nexport function loadAudience(): AiAudience | null {\n try {\n const raw = localStorage.getItem(AUDIENCE_KEY);\n return raw && getAiAudience(raw) ? (raw as AiAudience) : null;\n } catch {\n return null;\n }\n}\n\nexport function rememberAudience(audience: AiAudience): void {\n if (!getAiAudience(audience)) {return;}\n try {\n localStorage.setItem(AUDIENCE_KEY, audience);\n } catch {\n // Storage refused: the choice is not remembered.\n }\n}\n\nconst THINKING_LEVELS: readonly AiThinkingLevel[] = ['off', 'low', 'medium', 'high'];\n\n/** The remembered thinking level, or null for \"Default\" (MikeDown picks per task). */\nexport function loadThinkingLevel(): AiThinkingLevel | null {\n try {\n const raw = localStorage.getItem(THINKING_KEY);\n return raw && (THINKING_LEVELS as readonly string[]).includes(raw) ? (raw as AiThinkingLevel) : null;\n } catch {\n return null;\n }\n}\n\n/** Remember a thinking level; null goes back to \"Default\". */\nexport function rememberThinkingLevel(level: AiThinkingLevel | null): void {\n try {\n if (level) {localStorage.setItem(THINKING_KEY, level);} else {localStorage.removeItem(THINKING_KEY);}\n } catch {\n // Storage refused: the choice is not remembered.\n }\n}\n\n/**\n * The remembered level for a request to this kind: the level itself when\n * the kind has it, else the nearest one (Off on Anthropic is Low, any tier\n * on LM Studio is On). Null for \"Default\" or a kind with no mapping.\n */\nexport function thinkingLevelFor(kind: string): AiThinkingLevel | null {\n return nearestThinkingLevel(kind, loadThinkingLevel());\n}\n","/**\n * The Settings modal's AI tab: a summary. Built only when the host has an\n * `ai` group (see `editor.ts#showSettingsModal`), with the modal's own row\n * builders so it sits flush with the other tabs.\n *\n * Order (U8): the intro, the master switch, the Engines summary, Allow\n * cloud with the cloud consents, the toolbar button switch, Features.\n * Tier 1 hosts (`complete` only, they route by themselves) get the master\n * switch, the toolbar switch and the feature toggles. Tier 2 hosts (an\n * engine registry) also get a compact engine list (name, local/cloud pill,\n * status dot, enabled switch), the default model with \"Change…\" (the Tasks\n * section), \"Manage engines…\", Allow cloud, and each feature's task under\n * \"Advanced: task per feature\".\n * Engines, their forms and routing live on the AI Engines page\n * (`ai-engines-page.ts`), which the tab opens over the modal.\n *\n * Edits run in an `AiSettingsSession` (`ai-settings-session.ts`); Save sends\n * only the `ai.*` keys that changed, through the modal's normal\n * `saveSettings` patch. The page starts from the tab's draft and saves on\n * Done; the tab then takes the saved result as its own.\n *\n * Modal UI only: nothing here touches the editor document or its DOM.\n */\n\nimport { AI_FEATURES, AI_NO_CONSENTS_TEXT, AI_TASKS, aiConsentStepNote, aiConsentSummary, aiProviderPolicy, getAiTask, resolveAiFeature, toAiError } from './ai';\nimport type { AiConsentRecord, AiEngineConfig, AiSettings, AiSettingsPatch } from './ai';\nimport { engineDisplayName, engineKindLabel, parseLocalNetworksText, routeLabel, taskRouteNote } from './ai-settings-model';\nimport { createAiSettingsSession } from './ai-settings-session';\nimport type { AiSettingsSessionOptions } from './ai-settings-session';\nimport type { AiEnginesPageSection } from './ai-engines-page';\nimport { ICONS, button, el, experimentalBadge, experimentalDisclaimer, keepFocus, kindGlyphHtml, localityPills, nextId, note, privacyCard, statusBadge, switchInput } from './ai-settings-dom';\nimport type { MikeDownSettingsSectionBuild, MikeDownSettingsSectionContext } from './types';\n\n/** The tab asks its host to open the AI Engines page over the modal. */\nexport interface AiEnginesPageRequest {\n initial?: { engineId?: string; section?: AiEnginesPageSection };\n /** Session options for the page: it starts from the tab's draft. */\n session: AiSettingsSessionOptions & { keyOverride: Map<string, boolean> };\n /** The page saved (Done) `patch`, ending at `settings`. */\n onDone(patch: AiSettingsPatch, settings: AiSettings): void;\n}\n\nexport interface AiSettingsSectionOptions extends AiSettingsSessionOptions {\n /** The modal saved; the draft is the new settings. */\n onSaved(draft: AiSettings): void;\n /** Open the AI Engines page. Absent: no engine list and no Manage engines… button. */\n openEnginesPage?(request: AiEnginesPageRequest): void;\n /** A stored consent was forgotten: drop this session's copy of the answer so the next request asks again. */\n onConsentForgotten?(engineId: string): void;\n}\n\n// ── The tab ─────────────────────────────────────────────────────────────────\n\nexport function buildAiSettingsSection(ctx: MikeDownSettingsSectionContext, opts: AiSettingsSectionOptions): MikeDownSettingsSectionBuild {\n const session = createAiSettingsSession(opts);\n const { tier } = session;\n const canManage = tier === 2 && !!opts.openEnginesPage;\n\n // Screen reader announcements (the page saved).\n const live = el('div', 'ai-live');\n live.setAttribute('role', 'status');\n live.setAttribute('aria-live', 'polite');\n let liveTimer: number | undefined;\n function announce(text: string): void {\n window.clearTimeout(liveTimer);\n live.textContent = '';\n liveTimer = window.setTimeout(() => { live.textContent = text; }, 40);\n }\n\n // ── Experimental notice, master switch and Allow cloud ────────────────────\n const rows: HTMLElement[] = [];\n\n const intro = el('div', 'ai-experimental-intro');\n const introHead = el('div', 'ai-experimental-head');\n introHead.append(el('span', 'ai-experimental-title', 'AI features'), experimentalBadge());\n intro.append(introHead, experimentalDisclaimer());\n rows.push(intro);\n\n const masterField = ctx.makeCheckboxRow(\n 'Enable AI features',\n tier === 2\n ? 'Writing help from engines you choose. While this is off, nothing is sent anywhere.'\n : 'Writing help from the AI service this app provides. While this is off, nothing is sent anywhere.',\n session.draft.enabled,\n );\n masterField.row.classList.add('ai-master');\n masterField.input.dataset.fk = 'ai-enabled';\n masterField.input.addEventListener('change', () => {\n session.draft = { ...session.draft, enabled: masterField.input.checked };\n });\n\n const toolbarField = ctx.makeCheckboxRow(\n 'Show AI button on the toolbar',\n 'Opens the AI actions. While AI is off, it offers to turn AI on and set it up.',\n session.draft.showToolbarButton,\n );\n toolbarField.input.dataset.fk = 'ai-toolbar-button';\n toolbarField.input.addEventListener('change', () => {\n session.draft = { ...session.draft, showToolbarButton: toolbarField.input.checked };\n });\n\n const cloudField = ctx.makeCheckboxRow(\n 'Allow cloud engines',\n 'Lets tasks use engines outside this network, such as Anthropic or OpenAI. Local engines never need it.',\n session.draft.allowCloud,\n );\n cloudField.input.dataset.fk = 'ai-allow-cloud';\n // What happens to the text, with the policies of the cloud engines set up\n // so far. Only promise a consent step when the host asks for one (OQ9).\n cloudField.row.append(privacyCard(session.draft.engines.map((e) => ({ policy: aiProviderPolicy(e) })), {\n openLink: ctx.openLink,\n extra: aiConsentStepNote(!!session.ai.requestCloudConsent),\n className: 'ai-row-note',\n }));\n cloudField.input.addEventListener('change', () => {\n session.draft = { ...session.draft, allowCloud: cloudField.input.checked };\n renderEngines();\n });\n\n // ── Cloud consents (only when the host stores answers it can list) ────────\n const listConsents = session.ai.listConsents?.bind(session.ai);\n const forgetConsent = session.ai.forgetConsent?.bind(session.ai);\n const consentsRow = ctx.makeRow('Cloud consents', 'Cloud engines you have allowed or refused here. Forget an answer to be asked again.');\n consentsRow.classList.add('ai-section');\n const consentsBody = el('div', 'ai-consents');\n consentsRow.append(consentsBody);\n\n function engineNameFor(engineId: string): string {\n const engine = session.draft.engines.find((e) => e.id === engineId);\n return engine ? engineDisplayName(engine) : engineId;\n }\n\n function renderConsents(records: AiConsentRecord[], problem?: string): void {\n keepFocus(consentsBody, () => {\n consentsBody.replaceChildren();\n if (problem) {consentsBody.append(note('error', problem));}\n if (records.length === 0) {\n if (!problem) {consentsBody.append(el('div', 'ai-consents-empty', AI_NO_CONSENTS_TEXT));}\n return;\n }\n const list = el('ul', 'ai-consents-list');\n list.setAttribute('aria-label', 'Cloud consents');\n for (const record of records) {\n const name = engineNameFor(record.engineId);\n const item = el('li', 'ai-consent');\n const forget = button('settings-btn settings-btn--secondary ai-consent-forget', 'Forget', { ariaLabel: `Forget the answer for ${name}`, fk: `consent-forget:${record.engineId}` });\n forget.addEventListener('click', () => {\n forget.disabled = true;\n void forgetConsent?.(record.engineId).then(\n () => {\n opts.onConsentForgotten?.(record.engineId);\n announce(`Forgot the answer for ${name}.`);\n return refreshConsents();\n },\n (err: unknown) => refreshConsents(toAiError(err).message),\n );\n });\n item.append(el('span', 'ai-consent-text', aiConsentSummary(record, name)), forget);\n list.append(item);\n }\n consentsBody.append(list);\n });\n }\n\n async function refreshConsents(problem?: string): Promise<void> {\n if (!listConsents) {return;}\n try {\n renderConsents(await listConsents(), problem);\n } catch (err) {\n renderConsents([], toAiError(err).message);\n }\n }\n\n // ── Engines (summary) ─────────────────────────────────────────────────────\n const enginesRow = ctx.makeRow('Engines', 'Servers that run the models. Local engines keep your text on this network.');\n enginesRow.classList.add('ai-section');\n const enginesBody = el('div', 'ai-engines-body');\n enginesRow.append(enginesBody);\n\n function openPage(initial?: AiEnginesPageRequest['initial']): void {\n // \"Enable AI features\" ticked but not saved yet: the page saves it with the engines (Q2).\n const pendingEnable = session.draft.enabled && !session.original.enabled;\n opts.openEnginesPage?.({\n initial,\n session: { ...session.fork(), pendingEnable },\n onDone: (patch, saved) => {\n session.absorb(saved, patch);\n cloudField.input.checked = session.draft.allowCloud;\n masterField.input.checked = session.draft.enabled;\n renderEngines();\n if (Object.keys(patch).length > 0) {announce('Engines and tasks saved.');}\n },\n });\n }\n\n function renderEngines(): void {\n keepFocus(enginesBody, () => {\n enginesBody.replaceChildren();\n const draft = session.draft;\n if (draft.engines.length === 0) {\n const empty = el('div', 'ai-summary-empty');\n empty.append(\n el('div', 'ai-empty-title', 'No engines yet'),\n el('div', 'ai-empty-text', `Two ways to connect: paste a cloud API key, or run models on your own machine.${draft.enabled ? '' : ' Nothing is sent until AI is on.'}`),\n );\n enginesBody.append(empty);\n } else {\n const list = el('div', 'ai-engines ai-engines--compact');\n list.setAttribute('role', 'list');\n list.setAttribute('aria-label', 'Engines');\n for (const engine of draft.engines) {list.append(buildEngineItem(engine));}\n enginesBody.append(list, buildRouteLine());\n }\n const manage = button('settings-btn settings-btn--secondary ai-manage-btn', draft.engines.length === 0 ? 'Add engine…' : 'Manage engines…', { fk: 'manage-engines' });\n manage.addEventListener('click', () => openPage());\n const actions = el('div', 'ai-summary-actions');\n actions.append(manage);\n enginesBody.append(actions);\n });\n }\n\n function buildEngineItem(engine: AiEngineConfig): HTMLElement {\n const item = el('div', 'ai-engine ai-engine--compact');\n item.setAttribute('role', 'listitem');\n item.dataset.engineId = engine.id;\n item.classList.toggle('is-disabled', !engine.enabled);\n const name = engineDisplayName(engine);\n\n const head = el('div', 'ai-engine-head');\n const glyph = el('span', 'ai-engine-glyph');\n glyph.innerHTML = kindGlyphHtml(engine.kind, 'ai-glyph--sm');\n // The name opens the page on this engine, like a list of services.\n const open = button('ai-engine-main ai-engine-open', '', { ariaLabel: `${name}: open in AI Engines`, fk: `eng:${engine.id}:open` });\n const titleLine = el('span', 'ai-engine-title');\n titleLine.append(el('span', 'ai-engine-name', name), ...localityPills(engine, session.draft));\n open.title = engineKindLabel(engine.kind);\n open.append(titleLine);\n open.addEventListener('click', () => openPage({ engineId: engine.id }));\n\n const enabled = switchInput(engine.enabled, `Enable ${name}`, `eng:${engine.id}:enabled-row`);\n enabled.addEventListener('change', () => {\n session.updateEngine(engine.id, { enabled: enabled.checked });\n renderEngines();\n });\n\n const actions = el('div', 'ai-engine-actions');\n actions.append(statusBadge(session.statuses.get(engine.id), undefined, { compact: true }), enabled);\n head.append(glyph, open, actions);\n item.append(head);\n return item;\n }\n\n /** \"Default model: oMLX (Mac Studio) · Qwen 3.8 Flash Next Change…\" */\n function buildRouteLine(): HTMLElement {\n const draft = session.draft;\n const line = el('div', 'ai-route-line');\n const labelId = nextId('ai-route-line');\n const label = el('span', 'ai-route-line-label', 'Default model');\n label.id = labelId;\n const value = el('span', 'ai-route-line-value', draft.routing.default ? routeLabel(draft, draft.routing.default) : 'None set');\n value.classList.toggle('is-none', !draft.routing.default);\n const change = button('ai-link-btn', 'Change…', { fk: 'route:change', ariaLabel: 'Change the default model' });\n change.setAttribute('aria-describedby', labelId);\n change.addEventListener('click', () => openPage({ section: 'routing' }));\n line.append(label, value, change);\n const n = draft.routing.default\n ? taskRouteNote({ ...draft, routing: { ...draft.routing, tasks: {} } }, session.statusList(), 'chat')\n : { level: 'info' as const, text: 'Tasks have nowhere to go until a default model is set.' };\n if (n) {line.append(note(n.level, n.text, 'ai-row-note'));}\n return line;\n }\n\n // ── Features ──────────────────────────────────────────────────────────────\n // One switch per feature. On tier 2 the task each feature routes through\n // is under \"Advanced: task per feature\" (U8): most people never change it.\n\n const featuresRow = ctx.makeRow('Features', 'Turn each feature on or off.');\n featuresRow.classList.add('ai-section');\n const featureRows: HTMLElement[] = [];\n const taskRows: HTMLElement[] = [];\n for (const def of AI_FEATURES) {\n const planned = def.status === 'planned';\n const resolved = resolveAiFeature(session.draft.features, def.id);\n const row = el('div', 'settings-row settings-row--inline ai-feature');\n row.classList.toggle('is-planned', planned);\n const text = el('div', 'settings-row-text');\n const labelId = nextId('ai-feature');\n const lbl = el('span', 'settings-label', def.label);\n lbl.id = labelId;\n text.append(lbl, el('span', 'settings-desc', def.description));\n const controls = el('div', 'ai-feature-controls');\n if (planned) {\n controls.append(el('span', 'ai-pill ai-pill--soon', 'Coming later'));\n row.setAttribute('aria-disabled', 'true');\n } else {\n if (tier === 2) {taskRows.push(buildTaskRow(def));}\n const toggle = switchInput(resolved.enabled, def.label, `feature:${def.id}:enabled`);\n toggle.setAttribute('aria-labelledby', labelId);\n toggle.removeAttribute('aria-label');\n toggle.addEventListener('change', () => {\n const draft = session.draft;\n session.draft = { ...draft, features: { ...draft.features, [def.id]: { ...(draft.features[def.id] ?? {}), enabled: toggle.checked } } };\n });\n controls.append(toggle);\n }\n row.append(text, controls);\n featureRows.push(row);\n }\n featuresRow.append(ctx.makeGroup(...featureRows));\n if (taskRows.length > 0) {featuresRow.append(...buildTaskDisclosure(taskRows));}\n\n /** One feature's task picker: \"Default task (Rewrite)\" or another task's route. */\n function buildTaskRow(def: (typeof AI_FEATURES)[number]): HTMLElement {\n const defaultTask = getAiTask(def.defaultTask);\n const row = el('div', 'settings-row settings-row--inline ai-feature-task');\n const labelId = nextId('ai-feature-task');\n const lbl = el('span', 'settings-label', def.label);\n lbl.id = labelId;\n const select = el('select', 'settings-input settings-input--small');\n select.dataset.fk = `feature:${def.id}:task`;\n select.setAttribute('aria-label', `Task route for ${def.label}`);\n const dflt = el('option', '', `Default task (${defaultTask?.label ?? def.defaultTask})`);\n dflt.value = '';\n select.append(dflt);\n for (const task of AI_TASKS) {\n if (task.hostMethod) {continue;}\n const o = el('option', '', task.label);\n o.value = task.id;\n select.append(o);\n }\n const saved = session.draft.features[def.id]?.task;\n if (saved && !AI_TASKS.some((t) => t.id === saved)) {\n const o = el('option', '', saved);\n o.value = saved;\n select.append(o);\n }\n select.value = saved ?? '';\n select.addEventListener('change', () => {\n const draft = session.draft;\n const entry = { ...(draft.features[def.id] ?? {}) };\n if (select.value) {entry.task = select.value;} else {delete entry.task;}\n session.draft = { ...draft, features: { ...draft.features, [def.id]: entry } };\n });\n row.append(lbl, select);\n return row;\n }\n\n /** \"Advanced: task per feature\", closed until opened; a feature can use another task's model. */\n function buildTaskDisclosure(taskRowsIn: HTMLElement[]): HTMLElement[] {\n const panelId = nextId('ai-feature-tasks');\n const toggle = button('ai-disclosure ai-feature-tasks-toggle', 'Advanced: task per feature', { html: ICONS.chevron, fk: 'features:advanced' });\n toggle.setAttribute('aria-expanded', 'false');\n toggle.setAttribute('aria-controls', panelId);\n const panel = el('div', 'ai-advanced ai-feature-tasks');\n panel.id = panelId;\n panel.hidden = true;\n panel.append(el('div', 'settings-desc', 'Each feature uses its own task’s model (see Tasks on the AI Engines page). Pick another task to borrow its model.'), ctx.makeGroup(...taskRowsIn));\n toggle.addEventListener('click', () => {\n panel.hidden = !panel.hidden;\n toggle.setAttribute('aria-expanded', String(!panel.hidden));\n });\n return [toggle, panel];\n }\n\n // ── Local networks ────────────────────────────────────────────────────────\n // A power-user list (tier 2 only): extra ranges and host-name suffixes that\n // count as local, so an engine there needs no Allow cloud. The host saves\n // it to user settings only; a repo cannot widen it.\n\n const localNetsRow = ctx.makeRow('Local networks', 'Networks and host names that count as local, so an engine there never needs Allow cloud.');\n localNetsRow.classList.add('ai-section');\n {\n const panelId = nextId('ai-local-networks');\n const toggle = button('ai-disclosure ai-local-networks-toggle', 'Advanced: local networks', { html: ICONS.chevron, fk: 'local-networks:advanced' });\n toggle.setAttribute('aria-expanded', 'false');\n toggle.setAttribute('aria-controls', panelId);\n const panel = el('div', 'ai-advanced ai-local-networks');\n panel.id = panelId;\n panel.hidden = true;\n\n const area = el('textarea', 'settings-input ai-mono ai-overrides-text');\n area.rows = 4;\n area.spellcheck = false;\n area.dataset.fk = 'ai-local-networks';\n area.placeholder = '10.0.98.0/24\\n.ts.net';\n area.value = session.draft.localNetworks.join('\\n');\n area.setAttribute('aria-label', 'Local networks, one per line');\n const err = el('div', 'ai-field-error');\n err.id = nextId('ai-local-networks-error');\n err.setAttribute('aria-live', 'polite');\n area.setAttribute('aria-describedby', err.id);\n area.addEventListener('input', () => {\n const parsed = parseLocalNetworksText(area.value);\n if (!parsed.ok) {\n err.textContent = parsed.error;\n area.setAttribute('aria-invalid', 'true');\n return;\n }\n err.textContent = '';\n area.removeAttribute('aria-invalid');\n session.draft = { ...session.draft, localNetworks: parsed.value };\n if (canManage) {renderEngines();}\n });\n // Leaving the field shows what was kept: normalized, or the defaults when blank.\n area.addEventListener('blur', () => {\n if (area.getAttribute('aria-invalid') !== 'true') {area.value = session.draft.localNetworks.join('\\n');}\n });\n panel.append(\n el('div', 'settings-desc', 'One per line. An IPv4 range such as 10.0.98.0/24 (a WireGuard network, say) or a host-name suffix such as .ts.net. Loopback, link-local, .local, .lan and .home.arpa always count. Leave it blank for the defaults (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Saved to your user settings only, never to a folder.'),\n area,\n err,\n );\n toggle.addEventListener('click', () => {\n panel.hidden = !panel.hidden;\n toggle.setAttribute('aria-expanded', String(!panel.hidden));\n });\n localNetsRow.append(toggle, panel);\n }\n\n // ── Assemble ──────────────────────────────────────────────────────────────\n\n // Intro, master switch, Engines (with the default model), Allow cloud and\n // its consents, the toolbar button, Features (U8).\n rows.push(masterField.row);\n if (tier === 2) {\n if (canManage) {\n rows.push(enginesRow);\n renderEngines();\n }\n rows.push(cloudField.row);\n if (listConsents && forgetConsent) {\n rows.push(consentsRow);\n void refreshConsents();\n }\n }\n rows.push(toolbarField.row, featuresRow);\n if (tier === 2) {rows.push(localNetsRow);}\n rows.push(live);\n\n // Statuses pushed while the tab is open refresh the dots in place.\n const unsubscribe = canManage ? opts.subscribeStatuses?.((list) => {\n if (!enginesRow.isConnected) {return;}\n for (const s of list) {session.statuses.set(s.engineId, s);}\n renderEngines();\n }) : undefined;\n\n // Fresh statuses as the tab opens: the dots should not be stale.\n if (canManage) {\n void session.refreshStatuses().then((ok) => {\n if (ok && enginesRow.isConnected) {renderEngines();}\n });\n }\n\n const close = () => {\n window.clearTimeout(liveTimer);\n unsubscribe?.();\n };\n\n return {\n rows,\n collect: () => session.collect(),\n onDiscarded: () => {\n close();\n session.discard();\n },\n onSaved: () => {\n close();\n opts.onSaved(session.commit());\n },\n };\n}\n","/**\n * The toolbar's AI button: when it shows, what a click opens, and the small\n * first-run panel it opens while AI is off.\n *\n * The button shows only for a host with an AI adapter (`host.ai` and the\n * `ai` feature) and while `ai.showToolbarButton` is on. With AI off, a click\n * opens the first-run panel: the title, one line of what AI does, the\n * Experimental badge and disclaimer, and Cancel plus one primary button. The disclaimer is one sentence with the full notice behind a link. On\n * a host that can look for local servers (`host.ai.detectLocalServers`) the\n * panel looks while it is open: a running server makes the primary button\n * \"Use LM Studio\" (one click: engine, models, default route, AI on) with\n * \"Set up another way…\" beside it, and one privacy line whose \"Learn more\"\n * opens the AI Engines page too; otherwise the primary is \"Set up\", which\n * opens the AI Engines page (on the setup wizard while there is no engine\n * yet), and AI turns on only at its Done (B3). A tier-1\n * host routes by itself: its button is \"Turn on\" and lands on the AI tab.\n * With AI on, a click opens a menu of every AI action (the same list as the\n * context menu's `AI` submenu), a Thinking row when the routed model can\n * think, and \"Manage engines…\".\n *\n * Toolbar chrome only: nothing here touches the editor document or its DOM.\n */\n\nimport type { AiSettings, AiThinkingChoice, AiThinkingLevel } from './ai';\nimport type { AiHostTier } from './ai-settings-model';\nimport { AI_EXPERIMENTAL_DISCLAIMER, button, el, experimentalBadge, nextId, privacyLine } from './ai-settings-dom';\nimport { AI_DETECT_LOOKING } from './ai-local-setup';\nimport { getPortal } from './portal';\nimport type { ToolbarDropdownEntry } from './toolbar-dropdown';\n\nexport { aiToolbarButtonMode, type AiToolbarButtonMode } from './ai-lite';\n\n/** The patch \"Turn on\" (tier 1) sends through `host.saveSettings`. Tier 2 turns AI on at the Engines page's Done instead. */\nexport const AI_TURN_ON_PATCH = { 'ai.enabled': true } as const;\n\n/** Where \"Set up\" (or \"Turn on\") lands. */\nexport type AiSetupTarget =\n | { kind: 'page'; engineId: string }\n | { kind: 'wizard' }\n | { kind: 'tab' };\n\n/**\n * \"Set up\": a tier-2 host opens the AI Engines page on the default route's\n * engine (its Express form), else the first engine; with no engine yet, the\n * page opens on the setup wizard (M1b). A tier-1 host routes by itself, so\n * it gets the AI tab and never the wizard.\n */\nexport function aiSetupTarget(tier: AiHostTier, settings: Pick<AiSettings, 'engines' | 'routing'>): AiSetupTarget {\n if (tier !== 2) {return { kind: 'tab' };}\n const byRoute = settings.routing.default?.engineId;\n const engineId = byRoute && settings.engines.some((e) => e.id === byRoute) ? byRoute : settings.engines[0]?.id;\n return engineId ? { kind: 'page', engineId } : { kind: 'wizard' };\n}\n\n// ── The menu (AI on) ────────────────────────────────────────────────────────\n\n/** An AI menu entry: enabled, or disabled with the reason as its hint; null leaves it out. */\nexport type AiToolbarEntryState = { enabled: true } | { enabled: false; hint: string } | null;\n\nexport interface AiToolbarMenuInput {\n /** Rewrite selection: null leaves it out (read-only), otherwise enabled or disabled with a hint. */\n rewrite: AiToolbarEntryState;\n /** \"Explain selection\": absent or null leaves it out. */\n explain?: AiToolbarEntryState;\n /** \"Translate…\" (the selection, or the whole document without one): absent or null leaves it out. */\n translate?: AiToolbarEntryState;\n /** \"Summarize document…\": absent or null leaves it out. A disabled hint carries the router's reason (D15). */\n summarize?: AiToolbarEntryState;\n /** \"Suggest titles…\": absent or null leaves it out. */\n titles?: AiToolbarEntryState;\n /** \"Suggest properties\" (the sidebar's Suggest): absent or null leaves it out. */\n properties?: AiToolbarEntryState;\n /**\n * The Thinking row near the bottom (it reads as a setting): Default plus\n * the levels the routed model's kind can express. Absent hides it (no\n * model that can think).\n */\n thinking?: AiToolbarThinkingRow;\n /** True for a host with an engine registry (\"Manage engines…\"); otherwise \"AI settings…\". */\n canManageEngines: boolean;\n icons: { rewrite: string; manage: string; explain?: string; translate?: string; summarize?: string; titles?: string; properties?: string };\n onRewrite(): void;\n onExplain?(): void;\n onTranslate?(): void;\n onSummarize?(): void;\n onSuggestTitles?(): void;\n onSuggestProperties?(): void;\n onManage(): void;\n /** \"Look again\" under the status row: retest the engine the menu is waiting on. Absent: no such row. */\n onRetest?(): void;\n}\n\nexport interface AiToolbarThinkingRow {\n /** `thinkingChoices(kind)` for the routed model (non-empty). */\n choices: AiThinkingChoice[];\n /** The remembered level; null is Default (the model's own). */\n value(): AiThinkingLevel | null;\n onChange(level: AiThinkingLevel | null): void;\n}\n\nconst THINKING_DEFAULT = 'default';\n\n/** The menu's Thinking row: the popover dial's pill, with Default first. */\nfunction thinkingRowEntry(row: AiToolbarThinkingRow): ToolbarDropdownEntry {\n // The dial's labels: Medium shortened to Med.\n const short = (label: string): string => (label === 'Medium' ? 'Med' : label);\n return {\n type: 'segmented',\n id: 'ai-thinking',\n label: 'Thinking',\n title: 'Thinking level for the next AI requests',\n options: [\n { value: THINKING_DEFAULT, label: 'Default', title: 'Thinking: the model\\'s default', spoken: 'Default' },\n ...row.choices.map((c) => ({ value: c.level, label: short(c.label), title: `Thinking: ${c.label}`, spoken: c.label })),\n ],\n value: () => row.value() ?? THINKING_DEFAULT,\n onChange: (v) => row.onChange(v === THINKING_DEFAULT ? null : v as AiThinkingLevel),\n classes: { group: 'ai-rw-think', label: 'ai-rw-think-label', segment: 'ai-rw-think-seg' },\n };\n}\n\n/** The per-item hint that differs by selection, so it never counts as one shared reason. */\nconst SELECT_TEXT_HINT = 'Select text first';\n\nconst UNREACHABLE_REASON = /could not reach|no answer|timed out|ECONNREFUSED|ENOTFOUND|EHOSTUNREACH|fetch failed|connection refused/i;\n\n/**\n * A short status line for a reason shared by several disabled items: \"oMLX\n * isn't reachable\" with the full reason as its muted second line, or the\n * reason as is when it has no better short form.\n */\nexport function aiMenuStatusLine(reason: string): { label: string; detail?: string } {\n const failed = /^(.+?) failed its last connection test/.exec(reason);\n if (!failed) {return { label: reason };}\n return UNREACHABLE_REASON.test(reason)\n ? { label: `${failed[1]} isn't reachable`, detail: reason }\n : { label: `${failed[1]} failed its last connection test`, detail: reason.slice(failed[0].length).replace(/^[:.\\s]+/, '') || undefined };\n}\n\n/** The reason two or more disabled items share (not \"Select text first\"), or null. */\nfunction sharedDisabledReason(states: readonly (AiToolbarEntryState | undefined)[]): string | null {\n const counts = new Map<string, number>();\n for (const state of states) {\n if (state && !state.enabled && state.hint !== SELECT_TEXT_HINT) {counts.set(state.hint, (counts.get(state.hint) ?? 0) + 1);}\n }\n let best: string | null = null;\n for (const [hint, n] of counts) {\n if (n >= 2 && (best === null || n > counts.get(best)!)) {best = hint;}\n }\n return best;\n}\n\n/**\n * The AI menu: one flat list, the same as the context menu's `AI` submenu\n * and the commands (U1): the selection actions, the document actions, the\n * Thinking row, then Manage engines…. No submenus (D14).\n */\nexport function aiToolbarMenuEntries(input: AiToolbarMenuInput): ToolbarDropdownEntry[] {\n const entries: ToolbarDropdownEntry[] = [];\n const separate = (): void => {\n if (entries.length > 0 && entries[entries.length - 1].type !== 'separator') {entries.push({ type: 'separator' });}\n };\n // A reason several items share (an engine that cannot be reached) shows once\n // as a status row on top; the items just grey out.\n const shared = sharedDisabledReason([input.rewrite, input.explain, input.translate, input.summarize, input.titles, input.properties]);\n if (shared) {\n const { label, detail } = aiMenuStatusLine(shared);\n entries.push({ type: 'status', id: 'ai-status', label, ...(detail ? { detail } : {}) });\n if (input.onRetest) {\n entries.push({ type: 'action', id: 'ai-retest', label: 'Look again', action: () => input.onRetest?.() });\n }\n entries.push({ type: 'separator' });\n }\n const add = (id: string, label: string, icon: string | undefined, state: AiToolbarEntryState | undefined, run: () => void): void => {\n if (!state) {return;}\n entries.push({\n type: 'action',\n id,\n label,\n icon: icon ?? input.icons.rewrite,\n hint: state.enabled || state.hint === shared ? undefined : state.hint,\n isDisabled: () => !state.enabled,\n action: run,\n });\n };\n add('ai-rewrite', 'Rewrite selection', input.icons.rewrite, input.rewrite, () => input.onRewrite());\n add('ai-explain', 'Explain selection', input.icons.explain, input.explain, () => input.onExplain?.());\n add('ai-translate', 'Translate…', input.icons.translate, input.translate, () => input.onTranslate?.());\n separate();\n add('ai-summarize', 'Summarize document…', input.icons.summarize, input.summarize, () => input.onSummarize?.());\n add('ai-titles', 'Suggest titles…', input.icons.titles, input.titles, () => input.onSuggestTitles?.());\n add('ai-properties', 'Suggest properties', input.icons.properties, input.properties, () => input.onSuggestProperties?.());\n if (input.thinking && input.thinking.choices.length > 0) {\n separate();\n entries.push(thinkingRowEntry(input.thinking));\n }\n separate();\n entries.push({\n type: 'action',\n id: 'ai-manage',\n label: input.canManageEngines ? 'Manage engines…' : 'AI settings…',\n icon: input.icons.manage,\n action: () => input.onManage(),\n });\n return entries;\n}\n\n// ── The first-run panel (AI off) ────────────────────────────────────────────\n\n/** What local server detection found, for the panel. */\nexport type AiFirstRunDetection =\n /** A server is running and not set up yet: the primary button offers it. */\n | { kind: 'found'; presetId: string; name: string; models?: number }\n /** Nothing answered: say so, with where to go instead. */\n | { kind: 'none' }\n /** Nothing new to offer (a running server is already set up, or detection failed): say nothing. */\n | { kind: 'quiet' };\n\nexport interface AiFirstRunPanelOptions {\n anchor: HTMLElement;\n /** 1: the host routes by itself, so the button only turns AI on (\"Turn on\"). Default 2 (\"Set up\"). */\n tier?: AiHostTier;\n /** \"Set up\" (or \"Turn on\", or \"Set up another way…\"). The panel is already closed. */\n onTurnOn(): void;\n /** Look for local servers while the panel is open. Aborted when it closes. */\n detect?(signal: AbortSignal): Promise<AiFirstRunDetection>;\n /** \"Use LM Studio\": set it up and turn AI on. Rejects with an Error whose message the panel shows. */\n onUseLocal?(presetId: string): Promise<void>;\n}\n\nexport interface AiFirstRunPanelHandle {\n readonly element: HTMLElement;\n /** Close without turning anything on. */\n close(): void;\n}\n\n/** The one line of verbs under the title (U9). */\nexport const AI_FIRST_RUN_VERBS = 'Rewrite, translate, explain, summarize, suggest titles and tags.';\n\n/** The panel's disclaimer in one sentence; \"Read the full notice\" reveals `AI_EXPERIMENTAL_DISCLAIMER`. */\nexport const AI_FIRST_RUN_NOTICE = 'AI features are experimental, and AI output can be wrong, so review it.';\n\n/** When no local server answered: lead with connecting a provider, local is the advanced option. */\nexport const AI_FIRST_RUN_NONE = 'Connect a provider you already use. Running models on this machine is under Advanced.';\n\n/** \"LM Studio is running on this computer, 3 models.\" */\nexport function aiDetectFoundText(name: string, models?: number): string {\n const count = models === undefined ? '' : `, ${models} ${models === 1 ? 'model' : 'models'}`;\n return `${name} is running on this computer${count}.`;\n}\n\nlet openPanel: { element: HTMLElement; close(restore: boolean): void } | null = null;\n\nexport function isAiFirstRunPanelOpen(): boolean {\n return openPanel !== null;\n}\n\nexport function hideAiFirstRunPanel(): void {\n openPanel?.close(false);\n}\n\n/**\n * Open the panel under `anchor` (one at a time) and focus its primary button.\n * With `detect`, a quiet status line looks for local servers; when one is\n * running, the primary button becomes \"Use <name>\" and \"Set up another way…\"\n * opens setup as before.\n */\nexport function showAiFirstRunPanel(opts: AiFirstRunPanelOptions): AiFirstRunPanelHandle {\n hideAiFirstRunPanel();\n const { anchor } = opts;\n const tier1 = opts.tier === 1;\n const setUpLabel = tier1 ? 'Turn on' : 'Set up';\n\n const panel = el('div', 'ai-first-run');\n panel.setAttribute('role', 'dialog');\n const titleId = nextId('ai-first-run-title');\n const textId = nextId('ai-first-run-text');\n panel.setAttribute('aria-labelledby', titleId);\n panel.setAttribute('aria-describedby', textId);\n\n const head = el('div', 'ai-experimental-head');\n const title = el('span', 'ai-experimental-title', 'AI features');\n title.id = titleId;\n head.append(title, experimentalBadge());\n const verbs = el('p', 'ai-first-run-verbs', AI_FIRST_RUN_VERBS);\n const text = el('p', 'ai-disclaimer ai-first-run-notice', `${AI_FIRST_RUN_NOTICE} `);\n text.id = textId;\n const notice = button('ai-link-btn ai-first-run-notice-toggle', 'Read the full notice', { fk: 'ai-first-run:notice' });\n notice.setAttribute('aria-expanded', 'false');\n text.append(notice);\n const fullNotice = el('p', 'ai-disclaimer ai-first-run-notice-full', AI_EXPERIMENTAL_DISCLAIMER);\n fullNotice.id = nextId('ai-first-run-notice-full');\n fullNotice.hidden = true;\n notice.setAttribute('aria-controls', fullNotice.id);\n\n // Detection and setup progress: one quiet line, read out as it changes.\n const status = el('div', 'ai-first-run-status');\n status.setAttribute('role', 'status');\n status.setAttribute('aria-live', 'polite');\n status.hidden = true;\n\n const actions = el('div', 'ai-first-run-actions');\n const other = button('ai-link-btn ai-first-run-other', 'Set up another way…', { fk: 'ai-first-run:other' });\n other.hidden = true;\n const cancel = button('settings-btn settings-btn--secondary', 'Cancel', { fk: 'ai-first-run:cancel' });\n const primary = button('settings-btn settings-btn--primary', setUpLabel, { fk: 'ai-first-run:turn-on' });\n actions.append(other, cancel, primary);\n // Beside \"Set up another way…\" (which can lead to a cloud engine): local vs cloud in one line.\n const privacy = privacyLine(() => setUp());\n privacy.hidden = true;\n const learnMore = privacy.querySelector<HTMLButtonElement>('button')!;\n panel.append(head, verbs, text, fullNotice, status, privacy, actions);\n\n let found: Extract<AiFirstRunDetection, { kind: 'found' }> | null = null;\n let busy = false;\n const detectAbort = new AbortController();\n\n function setStatus(state: 'looking' | 'found' | 'none' | 'working' | 'error' | 'hidden', line = ''): void {\n status.hidden = state === 'hidden';\n status.dataset.state = state;\n status.replaceChildren();\n if (state === 'hidden') {return;}\n if (state === 'found') {\n const dot = el('span', 'ai-first-run-dot');\n dot.setAttribute('aria-hidden', 'true');\n status.append(dot);\n }\n status.append(el('span', '', line));\n }\n\n let closed = false;\n function close(restore: boolean): void {\n if (closed) {return;}\n closed = true;\n detectAbort.abort();\n document.removeEventListener('mousedown', onOutside, true);\n panel.removeEventListener('keydown', onKeydown);\n panel.remove();\n if (openPanel?.element === panel) {openPanel = null;}\n if (restore && anchor.isConnected) {anchor.focus({ preventScroll: true });}\n }\n\n function onOutside(e: MouseEvent): void {\n const target = e.target as Node;\n // The anchor toggles the panel itself. A setup in progress keeps it open.\n if (!busy && !panel.contains(target) && !anchor.contains(target)) {close(false);}\n }\n\n function onKeydown(e: KeyboardEvent): void {\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n if (!busy) {close(true);}\n } else if (e.key === 'Tab') {\n // Keep Tab on the panel's buttons.\n const order = [notice, learnMore, other, cancel, primary].filter((b) => !b.hidden && !b.closest('[hidden]') && !b.disabled);\n if (order.length === 0) {return;}\n e.preventDefault();\n const at = order.indexOf(document.activeElement as HTMLButtonElement);\n const next = at < 0 ? 0 : (at + (e.shiftKey ? order.length - 1 : 1)) % order.length;\n order[next].focus();\n }\n }\n\n function setUp(): void {\n close(false);\n opts.onTurnOn();\n }\n\n async function useLocal(server: Extract<AiFirstRunDetection, { kind: 'found' }>): Promise<void> {\n if (!opts.onUseLocal) {return;}\n busy = true;\n for (const b of [notice, learnMore, other, cancel, primary]) {b.disabled = true;}\n setStatus('working', `Setting up ${server.name}…`);\n try {\n await opts.onUseLocal(server.presetId);\n busy = false;\n close(true);\n } catch (err) {\n busy = false;\n if (closed) {return;}\n // Back to the plain panel: setup the long way is one click away.\n found = null;\n for (const b of [notice, learnMore, other, cancel, primary]) {b.disabled = false;}\n other.hidden = true;\n privacy.hidden = true;\n primary.textContent = setUpLabel;\n setStatus('error', err instanceof Error && err.message ? err.message : `${server.name} could not be set up.`);\n primary.focus({ preventScroll: true });\n }\n }\n\n notice.addEventListener('click', () => {\n fullNotice.hidden = !fullNotice.hidden;\n notice.setAttribute('aria-expanded', String(!fullNotice.hidden));\n notice.textContent = fullNotice.hidden ? 'Read the full notice' : 'Hide the full notice';\n position(panel, anchor);\n });\n cancel.addEventListener('click', () => close(true));\n other.addEventListener('click', () => setUp());\n primary.addEventListener('click', () => {\n if (found) {void useLocal(found);} else {setUp();}\n });\n panel.addEventListener('keydown', onKeydown);\n document.addEventListener('mousedown', onOutside, true);\n\n if (opts.detect && !tier1) {\n setStatus('looking', AI_DETECT_LOOKING);\n void opts.detect(detectAbort.signal).then(\n (result) => {\n if (closed || busy) {return;}\n if (result.kind === 'found' && opts.onUseLocal) {\n found = result;\n primary.textContent = `Use ${result.name}`;\n other.hidden = false;\n privacy.hidden = false;\n setStatus('found', aiDetectFoundText(result.name, result.models));\n } else if (result.kind === 'none') {\n setStatus('none', AI_FIRST_RUN_NONE);\n } else {\n setStatus('hidden');\n }\n position(panel, anchor);\n },\n () => { if (!closed && !busy) {setStatus('hidden');} },\n );\n }\n\n getPortal().appendChild(panel);\n position(panel, anchor);\n openPanel = { element: panel, close };\n primary.focus({ preventScroll: true });\n\n return { element: panel, close: () => close(true) };\n}\n\n/** Below the anchor (above when there is no room), inside the editor's box and the viewport. */\nfunction position(panel: HTMLElement, anchor: HTMLElement): void {\n const a = anchor.getBoundingClientRect();\n const p = panel.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const bounds = anchor.closest('.mikedown-root')?.getBoundingClientRect();\n const minLeft = Math.max(8, (bounds?.left ?? 0) + 8);\n const maxLeft = Math.min(vw, bounds?.right ?? vw) - p.width - 8;\n const left = Math.max(minLeft, Math.min(a.left + a.width / 2 - p.width / 2, maxLeft));\n const below = vh - a.bottom >= p.height + 6 || vh - a.bottom >= a.top;\n const top = below ? a.bottom + 6 : a.top - p.height - 6;\n panel.style.left = `${left}px`;\n panel.style.top = `${Math.max(8, Math.min(top, vh - p.height - 8))}px`;\n}\n","/**\n * One AI completion as the editor runs it: resolve the route, ask for cloud\n * consent when the router says so, send, and retry once on another engine\n * when the routed one turns out to be down before it sent a token.\n *\n * - Routing is recomputed on every request (`resolveRoute`, pure) from the\n * current settings, the last engine statuses and this session's consent.\n * - Consent: a grant (\"Allow for this workspace\") is remembered for the\n * session (the host persists it too). \"Allow once\" (`'once'`) covers only\n * the request that asked. A refusal (\"Don't allow\") applies here to that\n * request, so the fallback runs now; the host remembers it for the session\n * and answers the next attempt without a dialog. A stored `'never'` (older\n * versions) is kept for the session as a refusal, so the menu entries\n * disable with the router's reason.\n * - A tier-1 host (no `listEngines`) routes by itself: no route is sent.\n * - Thinking: a per-request level becomes the request's `requestOverrides`\n * (the kind's thinking fields only); the host merges them over the\n * model's own, so the request wins. Only for a routed engine whose kind\n * has a mapping (`thinkingChoices`). With no level (\"Default\") and none\n * set on the model, the job's default applies (`resolveThinkingLevel`:\n * Off for short edits). Such a model counts its reasoning\n * against `maxTokens`, so unless the effective level is Off the answer\n * budget gets reasoning headroom (`thinkingMaxTokens`).\n * - Cancellation is the caller's `AbortSignal`; the host aborts the request.\n */\n\nimport {\n CHARS_PER_TOKEN,\n isRouteUsable,\n makeAiError,\n resolveAiFeature,\n resolveRoute,\n resolveThinkingLevel,\n thinkingChoices,\n thinkingLevelFrom,\n thinkingMaxTokens,\n toAiError,\n withThinkingLevel,\n type AiThinkingJob,\n type AiThinkingLevel,\n type AiThinkingOptions,\n} from './ai';\nimport type {\n AiCompletionResult,\n AiConsentState,\n AiEngineStatus,\n AiError,\n AiErrorCode,\n AiMessage,\n AiRouteOk,\n AiRouteUnusable,\n AiSendsScope,\n AiSettings,\n MikeDownAiHost,\n} from './ai';\n\nexport interface AiRunContext {\n ai: MikeDownAiHost;\n settings: () => AiSettings;\n statuses: () => readonly AiEngineStatus[];\n /** Session consent answers by engine id (grants only are written back). */\n consent: Record<string, boolean | undefined>;\n}\n\nexport interface AiRunRequest {\n feature: string;\n /** What this request sends when it differs from the feature's own scope (whole-document Translate); for the consent dialog. */\n sends?: AiSendsScope;\n task?: string;\n messages: AiMessage[];\n maxTokens?: number;\n temperature?: number;\n format?: 'text' | 'json';\n /**\n * Thinking level for this request; null or absent sends none (the model's\n * configured overrides apply). A function is asked once the route's engine\n * kind is known, so a choice remembered per kind follows a fallback.\n */\n thinking?: AiThinkingLevel | null | ((kind: string) => AiThinkingLevel | null);\n /**\n * What the request is for, for the default thinking level when `thinking`\n * gives none (`taskThinkingDefault`); defaults to `feature`. `explain` and\n * `translate` run under the `rewrite` feature.\n */\n job?: AiThinkingJob;\n}\n\n/** The thinking dial's state for the route serving a request. */\nexport interface AiRunThinking {\n /** The routed engine's kind (`thinkingChoices(kind)` is non-empty). */\n kind: string;\n /** The level the model's own `requestOverrides` express (null: model default). */\n configured: AiThinkingLevel | null;\n /** The level this request sent (null: none, `configured` applies). */\n sent: AiThinkingLevel | null;\n /** `sent` is the job's default, not the user's choice: the dial still shows Default. */\n auto?: boolean;\n}\n\n/** Whether the model may have been thinking: a routed kind with a mapping whose effective level is not Off. */\nexport function aiRunThinkingOn(thinking: AiRunThinking | null): boolean {\n return !!thinking && (thinking.sent ?? thinking.configured) !== 'off';\n}\n\nexport interface AiRunEvents {\n /**\n * The route about to be used (null for a tier-1 host), before any token.\n * Called again on a retry. `thinking` is null when the route's kind has no\n * thinking mapping (and always for a tier-1 host).\n */\n onRoute?(route: AiRouteOk | null, thinking: AiRunThinking | null): void;\n /** A text delta, and everything received so far for the current attempt. */\n onToken?(delta: string, text: string): void;\n}\n\nexport interface AiRunOutcome {\n result: AiCompletionResult;\n route: AiRouteOk | null;\n viaFallback: boolean;\n thinking: AiRunThinking | null;\n}\n\ntype Json = Record<string, unknown>;\n\nconst isObject = (v: unknown): v is Json => typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/**\n * The per-request `requestOverrides` for one thinking level: the kind's\n * thinking fields only (`withThinkingLevel` on nothing). The host merges\n * them over the model's overrides, and a merge cannot delete, so a thinking\n * field the model sets that this level leaves out is sent at its neutral\n * value: `reasoning_effort: \"none\"`, or `chat_template_kwargs.enable_thinking:\n * true` (a model set to Off on a local engine, asked for a tier). Undefined\n * when the kind cannot express the level.\n */\nexport function thinkingRequestOverrides(\n kind: string,\n modelOverrides: Json | undefined,\n level: AiThinkingLevel,\n opts: AiThinkingOptions = {},\n): Json | undefined {\n const out = withThinkingLevel(kind, undefined, level, opts);\n if (!out || kind === 'anthropic' || !modelOverrides) {return out;}\n if (modelOverrides.reasoning_effort !== undefined && out.reasoning_effort === undefined) {out.reasoning_effort = 'none';}\n const modelKwargs = modelOverrides.chat_template_kwargs;\n const kwargs = isObject(out.chat_template_kwargs) ? out.chat_template_kwargs : {};\n if (isObject(modelKwargs) && modelKwargs.enable_thinking !== undefined && kwargs.enable_thinking === undefined) {\n out.chat_template_kwargs = { ...kwargs, enable_thinking: true };\n }\n return out;\n}\n\n/** The dial state and the overrides to send for `route`, or null when its kind has no mapping. */\nfunction routeThinking(settings: AiSettings, route: AiRouteOk, req: Pick<AiRunRequest, 'thinking' | 'job' | 'feature'>): { info: AiRunThinking; overrides?: Json; contextTokens: number | null } | null {\n const engine = settings.engines.find((e) => e.id === route.engineId);\n if (!engine || thinkingChoices(engine.kind).length === 0) {return null;}\n const model = engine.models.find((m) => m.id === route.modelId);\n const configured = thinkingLevelFrom(engine.kind, model?.requestOverrides);\n const wanted = req.thinking;\n const explicit = typeof wanted === 'function' ? wanted(engine.kind) : wanted ?? null;\n const { level, auto } = resolveThinkingLevel(engine.kind, explicit, configured, req.job ?? req.feature, { modelId: route.modelId });\n const overrides = level ? thinkingRequestOverrides(engine.kind, model?.requestOverrides, level, { local: route.isLocal }) : undefined;\n return {\n info: { kind: engine.kind, configured, sent: overrides ? level : null, ...(overrides && auto ? { auto: true } : {}) },\n ...(overrides ? { overrides } : {}),\n contextTokens: model?.capabilities.contextTokens ?? null,\n };\n}\n\n/** Rough prompt size in tokens (text parts only). */\nfunction promptTokens(messages: readonly AiMessage[]): number {\n let chars = 0;\n for (const m of messages) {\n if (typeof m.content === 'string') {chars += m.content.length;} else {\n for (const part of m.content) {if (part.type === 'text') {chars += part.text.length;}}\n }\n }\n return Math.ceil(chars / CHARS_PER_TOKEN);\n}\n\n/**\n * `maxTokens` for the request: the answer budget, plus reasoning headroom\n * when the routed model can think and the effective level (sent, else the\n * model's own, else model default) is not Off.\n */\nfunction requestMaxTokens(req: AiRunRequest, thinking: ReturnType<typeof routeThinking>): number | undefined {\n if (req.maxTokens === undefined || !thinking) {return req.maxTokens;}\n const level = thinking.info.sent ?? thinking.info.configured;\n return thinkingMaxTokens(req.maxTokens, level, { contextTokens: thinking.contextTokens, promptTokens: promptTokens(req.messages) });\n}\n\nlet requestCounter = 0;\n\nfunction nextRequestId(feature: string): string {\n requestCounter += 1;\n return `ai-${feature}-${Date.now().toString(36)}-${requestCounter}`;\n}\n\n/** An unusable route as the error the popover shows. */\nexport function routeUnusableError(r: AiRouteUnusable): AiError {\n const map: Partial<Record<AiRouteUnusable['unusable'], AiErrorCode>> = {\n cloudBlocked: 'cloudBlocked',\n consentDenied: 'consentDenied',\n probeFailed: 'unreachable',\n modelMissing: 'modelNotFound',\n modelNotListed: 'modelNotFound',\n };\n const e = makeAiError(map[r.unusable] ?? 'unknown', r.reason);\n return r.engineId ? { ...e, engineId: r.engineId } : e;\n}\n\nfunction isTier2(ai: MikeDownAiHost): boolean {\n return typeof ai.listEngines === 'function';\n}\n\n/** Statuses with the engines that failed during this run marked down, so the router passes them over. */\nfunction withFailures(statuses: readonly AiEngineStatus[], failed: ReadonlyMap<string, string>): AiEngineStatus[] {\n if (failed.size === 0) {return [...statuses];}\n const out = statuses.map((s) => (failed.has(s.engineId) ? { ...s, ok: false, error: failed.get(s.engineId) } : s));\n for (const [engineId, error] of failed) {\n if (!out.some((s) => s.engineId === engineId)) {out.push({ engineId, ok: false, isLocal: true, hasKey: false, error, models: [] });}\n }\n return out;\n}\n\nexport async function runAiCompletion(ctx: AiRunContext, req: AiRunRequest, events: AiRunEvents, signal: AbortSignal): Promise<AiRunOutcome> {\n const tier2 = isTier2(ctx.ai);\n const failed = new Map<string, string>();\n const refused: Record<string, boolean> = {};\n /** \"Allow once\" grants: this run only, never written to the session. */\n const once: Record<string, boolean> = {};\n let retried = false;\n\n // Bounded: each pass either sends, records a consent answer, or marks one engine failed.\n for (let pass = 0; pass < 12; pass++) {\n if (signal.aborted) {throw makeAiError('cancelled');}\n\n let route: AiRouteOk | null = null;\n if (tier2) {\n const consent: AiConsentState = { ...ctx.consent, ...once, ...refused };\n const resolved = resolveRoute(ctx.settings(), withFailures(ctx.statuses(), failed), consent, { feature: req.feature, ...(req.task ? { task: req.task } : {}) });\n if (!isRouteUsable(resolved)) {throw routeUnusableError(resolved);}\n if (resolved.needsConsent) {\n const reply = ctx.ai.requestCloudConsent\n ? await ctx.ai.requestCloudConsent(resolved.engineId, { feature: req.feature, ...(req.sends ? { sends: req.sends } : {}) })\n : true;\n if (signal.aborted) {throw makeAiError('cancelled');}\n if (reply === true) {ctx.consent[resolved.engineId] = true;}\n else if (reply === 'once') {once[resolved.engineId] = true;}\n else {\n refused[resolved.engineId] = false;\n // A stored refusal from an older version: the host will not ask again, so the\n // menu entries disable with the router's reason for the rest of the session.\n if (reply === 'never') {ctx.consent[resolved.engineId] = false;}\n }\n continue;\n }\n route = resolved;\n }\n\n const thinking = route ? routeThinking(ctx.settings(), route, req) : null;\n const maxTokens = requestMaxTokens(req, thinking);\n events.onRoute?.(route, thinking?.info ?? null);\n let text = '';\n let gotToken = false;\n try {\n const result = await ctx.ai.complete({\n requestId: nextRequestId(req.feature),\n feature: req.feature,\n task: route?.task ?? req.task ?? resolveAiFeature(ctx.settings().features, req.feature).task,\n ...(route ? { route: { engineId: route.engineId, modelId: route.modelId } } : {}),\n messages: req.messages,\n ...(req.format ? { format: req.format } : {}),\n ...(maxTokens !== undefined ? { maxTokens } : {}),\n ...(req.temperature !== undefined ? { temperature: req.temperature } : {}),\n ...(thinking?.overrides ? { requestOverrides: thinking.overrides } : {}),\n }, (delta) => {\n if (signal.aborted) {return;}\n gotToken = true;\n text += delta;\n events.onToken?.(delta, text);\n }, signal);\n return { result, route, viaFallback: route?.viaFallback ?? false, thinking: thinking?.info ?? null };\n } catch (err) {\n const e = signal.aborted ? makeAiError('cancelled') : toAiError(err);\n // The routed engine is down and nothing was shown yet: the host has\n // marked it failed; pass it over and try the fallback once.\n if (e.code === 'unreachable' && !gotToken && !retried && route) {\n retried = true;\n failed.set(route.engineId, e.message);\n continue;\n }\n // The popover's \"Open <engine>\" goes to the engine that failed.\n throw route && !e.engineId && e.code !== 'cancelled' ? { ...e, engineId: route.engineId } : e;\n }\n }\n throw makeAiError('unknown', 'No engine answered.');\n}\n\nexport type AiFeatureAvailability =\n | { state: 'hidden' }\n | { state: 'disabled'; reason: string }\n | { state: 'enabled' };\n\n/**\n * Whether a feature's entry points show: hidden without an AI host, with the\n * master switch or the feature off; disabled (with the router's reason) when\n * AI is on but nothing can serve it; enabled otherwise. A tier-1 host routes\n * by itself, so it is always enabled.\n */\nexport function aiFeatureAvailability(\n ai: MikeDownAiHost | undefined,\n settings: AiSettings,\n statuses: readonly AiEngineStatus[],\n consent: AiConsentState,\n feature: string,\n): AiFeatureAvailability {\n if (!ai || !settings.enabled) {return { state: 'hidden' };}\n if (!resolveAiFeature(settings.features, feature).enabled) {return { state: 'hidden' };}\n if (!isTier2(ai)) {return { state: 'enabled' };}\n // Grants and stored \"never\" answers count here (\"Allow once\" and \"Don't allow\"\n // are never written to the session, so the next attempt goes to the host).\n const answers: Record<string, boolean> = {};\n for (const [id, v] of Object.entries(consent)) {if (typeof v === 'boolean') {answers[id] = v;}}\n const r = resolveRoute(settings, statuses, answers, { feature });\n return isRouteUsable(r) ? { state: 'enabled' } : { state: 'disabled', reason: r.reason };\n}\n","/**\n * Selection rewrite (the `rewrite` AI feature): the popover that previews a\n * rewrite before it replaces the selection and the highlight that marks the\n * target while it is open.\n *\n * Transaction discipline (CLAUDE.md, brainstorm constraints 4, 5 and 7):\n *\n * - While the popover is open the target is marked with a decoration (a PM\n * plugin in rich text, a CM state field in source mode). Nothing streams\n * into the document and nothing touches `editor.view.dom`.\n * - Accept is one transaction: `tr.replaceRange` with the slice parsed from\n * the markdown result in rich text, one CM change in source mode. One undo\n * restores the original.\n * - Every new request (Retry, another variant, a new open) aborts the one\n * before it; Esc and click-away abort too.\n *\n * The popover renders model output through `renderPreviewMarkdown`, which\n * builds DOM with `textContent` only: no raw HTML, no link a click can follow.\n * Insert and Accept use the original markdown, not the rendered text.\n *\n * Three output modes, from the variant and the target:\n *\n * - `replace`: Accept replaces the selection (every variant but Explain).\n * - `readOnly`: Explain. Nothing changes unless Insert below is clicked,\n * which inserts the note as a blockquote after the target's block in one\n * transaction.\n * - `replaceDocument`: Translate with \"Whole document\". The target is the\n * body without its frontmatter; Accept replaces the body in one\n * transaction, puts the cursor at its start and scrolls to the top. A body\n * too long for the model's context is cut by `budgetDocument`: the first\n * part is translated, the rest is kept as it is, and a note says so.\n *\n * Two document jobs (the `summary` and `title` features) open the same\n * popover on a cursor target (`cursorInsertTarget`, `sourceCursorTarget`):\n *\n * - `insert` (`/summary`, `/outline`, \"Summarize document…\"): the summary\n * streams into the preview; Insert puts the block at the cursor's block\n * boundary in one transaction that also removes `/query`. TL;DR ⇄ Outline\n * in the header runs again.\n * - `choose` (`/title`, \"Suggest titles…\"): three candidates; a click hands\n * the title to the caller's `apply` (frontmatter `title:`, the H1, or a\n * new H1). One JSON repair round trip when the reply does not parse.\n */\n\nimport { elementFromString, posToDOMRect, type Editor } from '@tiptap/core';\nimport { TextSelection } from '@tiptap/pm/state';\nimport { DOMParser as PmDOMParser, Fragment, type Node as PmNode } from '@tiptap/pm/model';\nimport { closeHistory } from '@tiptap/pm/history';\nimport { EditorView as CmEditorView } from '@codemirror/view';\nimport { isolateHistory } from '@codemirror/commands';\nimport {\n CHARS_PER_TOKEN,\n DEFAULT_CONTEXT_TOKENS,\n aiErrorCopy,\n aiLengthLimitCopy,\n aiResultStats,\n aiResultStatsText,\n aiResultStatsTitle,\n budgetDocument,\n buildSummaryMessages,\n buildTitleMessages,\n coveragePercent,\n finalizeSummary,\n headingsOutline,\n jsonRepairMessages,\n makeAiError,\n parseTitles,\n renderHeadingOutline,\n summaryMaxTokens,\n summaryPreviewText,\n summaryVisibleText,\n thinkingChoices,\n titleMaxTokens,\n toAiError,\n whatIsSent,\n type AiSummaryKind,\n} from './ai';\nimport type { AiError, AiErrorCopy, AiMessage, AiResultStats, AiRouteOk, AiSendsScope, AiServedBy, AiThinkingLevel } from './ai';\nimport type { AiServedRequest } from './ai-settings-model';\nimport {\n AI_AUDIENCES,\n AI_REWRITE_VARIANTS,\n REWRITE_CONTEXT_CHARS,\n buildRewriteMessages,\n finalizeRewriteText,\n getAiAudience,\n getAiRewriteVariant,\n rewriteMaxTokens,\n rewriteVisibleText,\n type AiAudience,\n type AiRewriteGroup,\n type AiRewriteParams,\n type AiRewriteVariant,\n type AiRewriteVariantDefinition,\n} from './ai/prompts/rewrite';\nimport { buildExplainMessages, explainMaxTokens } from './ai/prompts/explain';\nimport { checkMarkdownStructure, type StructureDiff, type StructureMismatch } from './ai/prompts/structureCheck';\nimport type { AiRunEvents, AiRunOutcome, AiRunRequest, AiRunThinking } from './ai-request';\nimport { aiRunThinkingOn } from './ai-request';\nimport { renderPreviewMarkdown } from './ai-markdown-preview';\nimport {\n loadAudience,\n rememberAudience,\n rememberLanguage,\n rememberThinkingLevel,\n thinkingLevelFor,\n translateLanguageChoices,\n} from './ai-prefs';\nimport { getPortal } from './portal';\nimport { aiRewriteHighlightKey, cmRewriteRange, setCmRewriteRange, type Range } from './ai-rewrite-highlight';\n\nexport { AiRewriteHighlight, aiRewriteHighlightKey, cmAiRewriteHighlight } from './ai-rewrite-highlight';\n\nlet nextTargetId = 0;\n\n// ── Targets ─────────────────────────────────────────────────────────────────\n\n/** What the popover rewrites: one selection, or the whole body, in one view. */\nexport interface AiRewriteTarget {\n mode: 'rich' | 'source';\n /**\n * `document`: the whole body without its frontmatter (whole-document\n * translate). `cursor`: a caret or a `/query`, where a document job inserts.\n */\n scope: 'selection' | 'document' | 'cursor';\n /** The selection (or the body) as markdown. */\n text: string;\n before: string;\n after: string;\n /** More than one line: the popover shows old and new side by side. */\n multiline: boolean;\n /** False once the target text is gone (deleted, or the view was replaced). */\n alive(): boolean;\n /** Where the target is on screen now (null when it cannot be measured). */\n rect(): DOMRect | null;\n /** Replace the target in one transaction. False when the target is gone. */\n accept(markdown: string): boolean;\n /**\n * Insert `markdown` as a blockquote after the target's block (rich text) or\n * line (source), in one transaction. False when the target is gone or has\n * no block (a document target).\n */\n insertBelow(markdown: string): boolean;\n /** The document title, context for Explain (set by the caller). */\n title?: string;\n /** Drop the highlight. */\n release(): void;\n /** Give the keyboard back to the editor. */\n focus(): void;\n}\n\nfunction serializeFragment(editor: Editor, fragment: Fragment): string {\n const storage = (editor.storage as unknown as Record<string, { serializer?: { serialize(f: Fragment): string } }>).markdown;\n try {\n const md = storage?.serializer?.serialize(fragment);\n if (typeof md === 'string') {return md;}\n } catch { /* fall through to plain text */ }\n return fragment.textBetween(0, fragment.size, '\\n\\n');\n}\n\n/**\n * `doc` from `from` to `to` as markdown. The serializer only writes marks\n * (links, bold, code...) inside a text block, so a range within one block is\n * wrapped in a plain paragraph first: its marks survive and no block syntax\n * (a heading's `#`) is added. Code keeps its text as is.\n */\nfunction serializeRange(editor: Editor, doc: PmNode, from: number, to: number): string {\n const content = doc.slice(from, to).content;\n const parent = doc.resolve(from).parent;\n const paragraph = editor.state.schema.nodes.paragraph;\n if (content.firstChild?.isInline && !parent.type.spec.code && paragraph) {\n return serializeFragment(editor, Fragment.from(paragraph.create(null, content)));\n }\n return serializeFragment(editor, content);\n}\n\ntype MarkdownStorage = {\n parser?: { parse(md: string, o?: { inline?: boolean }): string };\n getMarkdown?(): string;\n};\n\nfunction markdownStorage(editor: Editor): MarkdownStorage | undefined {\n return (editor.storage as unknown as Record<string, MarkdownStorage>).markdown;\n}\n\n/** Markdown parsed into block content for the editor's schema. */\nfunction parseBlocks(editor: Editor, markdown: string): Fragment {\n const html = markdownStorage(editor)?.parser?.parse(markdown) ?? markdown;\n return PmDOMParser.fromSchema(editor.state.schema).parse(elementFromString(html)).content;\n}\n\n/** The text as a Markdown blockquote: every line quoted, blank lines kept as `>`. */\nexport function blockquoteMarkdown(text: string): string {\n return text.trim().split('\\n').map((line) => (line.trim() ? `> ${line}` : '>')).join('\\n');\n}\n\n/** A thin rect along the top of the visible part of `el`: where a document target \"is\". */\nfunction visibleTopRect(el: Element): DOMRect {\n const r = el.getBoundingClientRect();\n const top = Math.max(r.top, 8);\n return new DOMRect(r.left, top, Math.max(1, r.width), 1);\n}\n\nfunction rectUnion(a: { left: number; right: number; top: number; bottom: number }, b: { left: number; right: number; top: number; bottom: number }): DOMRect {\n const left = Math.min(a.left, b.left);\n const top = Math.min(a.top, b.top);\n return new DOMRect(left, top, Math.max(a.right, b.right) - left, Math.max(a.bottom, b.bottom) - top);\n}\n\n/**\n * The rich-text selection as a rewrite target, or null when there is nothing\n * to rewrite. An empty selection takes the text block around the caret.\n */\nexport function richRewriteTarget(editor: Editor): AiRewriteTarget | null {\n const { state } = editor;\n const sel = state.selection;\n // Table cell selections rewrite cell by cell badly; select the text instead.\n if ('$anchorCell' in sel) {return null;}\n let from = sel.from;\n let to = sel.to;\n if (sel.empty) {\n const $f = sel.$from;\n if (!$f.parent.isTextblock || $f.parent.type.spec.code || !$f.parent.textContent.trim()) {return null;}\n from = $f.start();\n to = $f.end();\n }\n const doc = state.doc;\n // Prose only: an image or another atom on its own is not rewritten.\n if (!doc.textBetween(from, to, ' ').trim()) {return null;}\n const text = serializeRange(editor, doc, from, to);\n if (!text.trim()) {return null;}\n\n // Context: the enclosing top-level block plus one on each side.\n const $from = doc.resolve(from);\n const $to = doc.resolve(to);\n const beforeStart = $from.depth > 0 ? $from.posAtIndex(Math.max(0, $from.index(0) - 1), 0) : 0;\n const afterEnd = $to.depth > 0 ? $to.posAtIndex(Math.min(doc.childCount, $to.index(0) + 2), 0) : doc.content.size;\n const before = beforeStart < from ? serializeRange(editor, doc, beforeStart, from) : '';\n const after = afterEnd > to ? serializeRange(editor, doc, to, afterEnd) : '';\n\n const id = ++nextTargetId;\n editor.view.dispatch(state.tr.setMeta(aiRewriteHighlightKey, { range: { from, to, id } }).setMeta('addToHistory', false));\n const range = (): Range | null => {\n if (editor.isDestroyed) {return null;}\n const r = aiRewriteHighlightKey.getState(editor.state);\n return r && r.id === id ? r : null;\n };\n\n return {\n mode: 'rich',\n scope: 'selection',\n text,\n before,\n after,\n multiline: text.trim().includes('\\n'),\n alive: () => !!range(),\n rect() {\n const r = range();\n if (!r) {return null;}\n try { return posToDOMRect(editor.view, r.from, r.to); } catch { return null; }\n },\n accept(markdown) {\n const r = range();\n if (!r || editor.isDestroyed) {return false;}\n const current = editor.state;\n const html = markdownStorage(editor)?.parser?.parse(markdown, { inline: true }) ?? markdown;\n const slice = PmDOMParser.fromSchema(current.schema).parseSlice(elementFromString(html), {\n preserveWhitespace: true,\n context: current.doc.resolve(r.from),\n });\n // Blocks replacing whole text blocks replace the blocks themselves, so\n // no empty paragraph is left behind.\n let { from, to } = r;\n const $a = current.doc.resolve(from);\n const $b = current.doc.resolve(to);\n if (slice.content.firstChild?.isBlock && $a.parent.isTextblock && $b.parent.isTextblock\n && $a.parentOffset === 0 && $b.parentOffset === $b.parent.content.size\n && $a.depth === $b.depth && $a.node($a.depth - 1) === $b.node($b.depth - 1)) {\n from = $a.before();\n to = $b.after();\n }\n // One transaction, its own undo step.\n const tr = closeHistory(current.tr).replaceRange(from, to, slice);\n tr.setMeta(aiRewriteHighlightKey, { range: null });\n const end = tr.mapping.map(to, 1);\n try {\n tr.setSelection(TextSelection.between(tr.doc.resolve(Math.min(from, tr.doc.content.size)), tr.doc.resolve(Math.min(end, tr.doc.content.size))));\n } catch { /* keep the mapped selection */ }\n editor.view.dispatch(tr.scrollIntoView());\n return true;\n },\n insertBelow(markdown) {\n const r = range();\n if (!r || editor.isDestroyed) {return false;}\n const current = editor.state;\n const content = parseBlocks(editor, blockquoteMarkdown(markdown));\n if (!content.size) {return false;}\n // After the top-level block that holds the end of the target, so a\n // selection inside a list or a table gets its note after the whole block.\n const $to = current.doc.resolve(r.to);\n const pos = $to.depth > 0 ? $to.after(1) : r.to;\n editor.view.dispatch(closeHistory(current.tr).insert(pos, content).scrollIntoView());\n return true;\n },\n release() {\n if (!range()) {return;}\n editor.view.dispatch(editor.state.tr.setMeta(aiRewriteHighlightKey, { range: null }).setMeta('addToHistory', false));\n },\n focus() {\n if (!editor.isDestroyed) {editor.view.focus();}\n },\n };\n}\n\n/** The source-mode selection as a rewrite target. An empty selection takes its line. */\nexport function sourceRewriteTarget(view: CmEditorView): AiRewriteTarget | null {\n const { state } = view;\n const sel = state.selection.main;\n let { from, to } = sel;\n if (sel.empty) {\n const line = state.doc.lineAt(from);\n if (!line.text.trim()) {return null;}\n from = line.from;\n to = line.to;\n }\n const text = state.sliceDoc(from, to);\n if (!text.trim()) {return null;}\n const before = state.sliceDoc(Math.max(0, from - REWRITE_CONTEXT_CHARS * 2), from);\n const after = state.sliceDoc(to, Math.min(state.doc.length, to + REWRITE_CONTEXT_CHARS * 2));\n\n const id = ++nextTargetId;\n view.dispatch({ effects: setCmRewriteRange.of({ from, to, id }) });\n const range = (): Range | null => {\n const r = view.state.field(cmRewriteRange, false);\n return r && r.id === id ? r : null;\n };\n\n return {\n mode: 'source',\n scope: 'selection',\n text,\n before,\n after,\n multiline: text.trim().includes('\\n'),\n alive: () => !!range(),\n rect() {\n const r = range();\n if (!r) {return null;}\n const a = view.coordsAtPos(r.from);\n const b = view.coordsAtPos(r.to, -1);\n if (!a || !b) {return a ? rectUnion(a, a) : b ? rectUnion(b, b) : null;}\n // A multi-line range spans the content's width.\n if (b.top > a.top + 1) {\n const content = view.contentDOM.getBoundingClientRect();\n return rectUnion(a, { ...b, left: content.left, right: Math.max(a.right, b.right) });\n }\n return rectUnion(a, b);\n },\n accept(markdown) {\n const r = range();\n if (!r) {return false;}\n // One CM transaction, isolated in history so one undo restores it.\n view.dispatch({\n changes: { from: r.from, to: r.to, insert: markdown },\n selection: { anchor: r.from, head: r.from + markdown.length },\n effects: setCmRewriteRange.of(null),\n annotations: isolateHistory.of('full'),\n userEvent: 'input.ai',\n scrollIntoView: true,\n });\n return true;\n },\n insertBelow(markdown) {\n const r = range();\n if (!r) {return false;}\n const doc = view.state.doc;\n // A selection that ends at the start of a line belongs to the line before.\n const endLine = doc.lineAt(r.to);\n const line = r.to > r.from && endLine.from === r.to ? doc.lineAt(r.to - 1) : endLine;\n const next = line.number < doc.lines ? doc.line(line.number + 1) : null;\n // A blank line before the quote, and one after it when text follows directly.\n const insert = `\\n\\n${blockquoteMarkdown(markdown)}${next && next.text.trim() ? '\\n' : ''}`;\n view.dispatch({\n changes: { from: line.to, insert },\n annotations: isolateHistory.of('full'),\n userEvent: 'input.ai',\n scrollIntoView: true,\n });\n return true;\n },\n release() {\n if (range()) {view.dispatch({ effects: setCmRewriteRange.of(null) });}\n },\n focus() {\n view.focus();\n },\n };\n}\n\n/**\n * The rich-text body as a whole-document target. The frontmatter is not in\n * the ProseMirror document (the editor keeps it apart), so Accept leaves it\n * byte-identical. `scrollToTop` runs after Accept to show the top of the page.\n */\nexport function richDocumentTarget(editor: Editor, opts: { scrollToTop?: () => void } = {}): AiRewriteTarget | null {\n if (editor.isDestroyed) {return null;}\n const text = markdownStorage(editor)?.getMarkdown?.() ?? editor.state.doc.textBetween(0, editor.state.doc.content.size, '\\n\\n');\n if (!text.trim()) {return null;}\n return {\n mode: 'rich',\n scope: 'document',\n text,\n before: '',\n after: '',\n multiline: false,\n alive: () => !editor.isDestroyed,\n rect: () => (editor.isDestroyed ? null : visibleTopRect(editor.view.dom)),\n accept(markdown) {\n if (editor.isDestroyed) {return false;}\n const current = editor.state;\n const content = parseBlocks(editor, markdown);\n if (!content.size) {return false;}\n // One transaction, its own undo step; the caret goes to the start of\n // the body and the view scrolls there (D13).\n const tr = closeHistory(current.tr).replaceWith(0, current.doc.content.size, content);\n tr.setMeta(aiRewriteHighlightKey, { range: null });\n tr.setSelection(TextSelection.atStart(tr.doc));\n editor.view.dispatch(tr.scrollIntoView());\n opts.scrollToTop?.();\n return true;\n },\n insertBelow: () => false,\n release() { /* no highlight */ },\n focus() {\n if (!editor.isDestroyed) {editor.view.focus();}\n },\n };\n}\n\n/**\n * The source-mode body as a whole-document target. `bodyStart` gives where\n * the body starts in the full text (after the frontmatter); only the body is\n * sent and replaced, so the YAML stays byte-identical.\n */\nexport function sourceDocumentTarget(view: CmEditorView, bodyStart: (markdown: string) => number): AiRewriteTarget | null {\n const full = view.state.doc.toString();\n const text = full.slice(bodyStart(full));\n if (!text.trim()) {return null;}\n return {\n mode: 'source',\n scope: 'document',\n text,\n before: '',\n after: '',\n multiline: false,\n alive: () => view.dom.isConnected,\n rect: () => visibleTopRect(view.scrollDOM),\n accept(markdown) {\n const current = view.state.doc.toString();\n const from = bodyStart(current);\n // One CM transaction, isolated in history; caret at the start of the\n // body, view at the top.\n view.dispatch({\n changes: { from, to: current.length, insert: markdown },\n selection: { anchor: from },\n effects: [setCmRewriteRange.of(null), CmEditorView.scrollIntoView(0, { y: 'start' })],\n annotations: isolateHistory.of('full'),\n userEvent: 'input.ai',\n });\n return true;\n },\n insertBelow: () => false,\n release() { /* no highlight */ },\n focus() {\n view.focus();\n },\n };\n}\n\n/** Where a document job inserts: the caret, or the `/query` it replaces. */\nexport interface AiCursorTarget extends AiRewriteTarget {\n /** The `/query` (from < to) or the caret (from === to), mapped through edits; null once gone. */\n range(): { from: number; to: number } | null;\n}\n\n/**\n * The rich-text caret, or a slash command's `/query`, as an insert target.\n * The `/query` is marked while the popover is open and stays in the\n * document until Accept, which removes it (with a mid-line trigger space)\n * and inserts the blocks in one transaction: in place of the caret's\n * top-level block when that is left an empty paragraph, else after it.\n * Cancel leaves the document untouched.\n */\nexport function cursorInsertTarget(editor: Editor, slash?: { from: number; to: number }): AiCursorTarget | null {\n if (editor.isDestroyed) {return null;}\n const { state } = editor;\n const id = ++nextTargetId;\n const head = state.selection.head;\n const initial: Range = slash && slash.to > slash.from\n ? { from: slash.from, to: slash.to, id }\n : { from: head, to: head, id, anchor: true };\n editor.view.dispatch(state.tr.setMeta(aiRewriteHighlightKey, { range: initial }).setMeta('addToHistory', false));\n const range = (): Range | null => {\n if (editor.isDestroyed) {return null;}\n const r = aiRewriteHighlightKey.getState(editor.state);\n return r && r.id === id ? r : null;\n };\n\n return {\n mode: 'rich',\n scope: 'cursor',\n text: '',\n before: '',\n after: '',\n multiline: false,\n alive: () => !!range(),\n range() {\n const r = range();\n return r ? { from: r.from, to: r.to } : null;\n },\n rect() {\n const r = range();\n if (!r) {return null;}\n try { return posToDOMRect(editor.view, r.from, r.to); } catch { return null; }\n },\n accept(markdown) {\n const r = range();\n if (!r || editor.isDestroyed) {return false;}\n const content = parseBlocks(editor, markdown);\n if (!content.size) {return false;}\n const current = editor.state;\n // One transaction, its own undo step: `/query` out, the blocks in.\n const tr = closeHistory(current.tr);\n let at = r.from;\n if (r.to > r.from) {\n const $q = current.doc.resolve(r.from);\n if ($q.parentOffset > 0 && current.doc.textBetween(r.from - 1, r.from) === ' ') {at = r.from - 1;}\n tr.delete(at, r.to);\n }\n tr.setMeta(aiRewriteHighlightKey, { range: null });\n const $at = tr.doc.resolve(Math.min(at, tr.doc.content.size));\n let from = $at.pos;\n let to = $at.pos;\n if ($at.depth > 0) {\n const block = $at.node(1);\n const empty = block.type.name === 'paragraph' && block.content.size === 0;\n from = empty ? $at.before(1) : $at.after(1);\n to = empty ? $at.after(1) : from;\n }\n tr.replaceWith(from, to, content);\n const end = Math.min(from + content.size, tr.doc.content.size);\n try { tr.setSelection(TextSelection.near(tr.doc.resolve(end), -1)); } catch { /* keep the mapped selection */ }\n editor.view.dispatch(tr.scrollIntoView());\n return true;\n },\n insertBelow: () => false,\n release() {\n if (!range()) {return;}\n editor.view.dispatch(editor.state.tr.setMeta(aiRewriteHighlightKey, { range: null }).setMeta('addToHistory', false));\n },\n focus() {\n if (!editor.isDestroyed) {editor.view.focus();}\n },\n };\n}\n\n/**\n * The source-mode caret as an insert target. Accept puts the markdown at the\n * caret's line in one CM transaction: in place of a blank line, else after\n * the line, with blank lines around it. A caret inside the frontmatter\n * inserts at the start of the body (`bodyStart`).\n */\nexport function sourceCursorTarget(view: CmEditorView, bodyStart?: (markdown: string) => number): AiCursorTarget {\n const id = ++nextTargetId;\n const head = view.state.selection.main.head;\n view.dispatch({ effects: setCmRewriteRange.of({ from: head, to: head, id, anchor: true }) });\n const range = (): Range | null => {\n const r = view.state.field(cmRewriteRange, false);\n return r && r.id === id ? r : null;\n };\n\n return {\n mode: 'source',\n scope: 'cursor',\n text: '',\n before: '',\n after: '',\n multiline: false,\n alive: () => !!range() && view.dom.isConnected,\n range() {\n const r = range();\n return r ? { from: r.from, to: r.to } : null;\n },\n rect() {\n const r = range();\n const c = r ? view.coordsAtPos(r.from) : null;\n return c ? rectUnion(c, c) : null;\n },\n accept(markdown) {\n const r = range();\n const md = markdown.trim();\n if (!r || !md) {return false;}\n const doc = view.state.doc;\n const start = bodyStart ? bodyStart(doc.toString()) : 0;\n const line = doc.lineAt(Math.max(r.from, Math.min(start, doc.length)));\n const prev = line.number > 1 ? doc.line(line.number - 1) : null;\n const next = line.number < doc.lines ? doc.line(line.number + 1) : null;\n const textAfter = !!next && !!next.text.trim();\n let changes: { from: number; to?: number; insert: string };\n let caret: number;\n if (!line.text.trim()) {\n const lead = prev && prev.text.trim() && line.from >= start ? '\\n' : '';\n changes = { from: line.from, to: line.to, insert: `${lead}${md}${textAfter ? '\\n' : ''}` };\n caret = line.from + lead.length + md.length;\n } else {\n changes = { from: line.to, insert: `\\n\\n${md}${textAfter ? '\\n' : ''}` };\n caret = line.to + 2 + md.length;\n }\n // One CM transaction, isolated in history so one undo removes it.\n view.dispatch({\n changes,\n selection: { anchor: caret },\n effects: setCmRewriteRange.of(null),\n annotations: isolateHistory.of('full'),\n userEvent: 'input.ai',\n scrollIntoView: true,\n });\n return true;\n },\n insertBelow: () => false,\n release() {\n if (range()) {view.dispatch({ effects: setCmRewriteRange.of(null) });}\n },\n focus() {\n view.focus();\n },\n };\n}\n\n// ── Titles ──────────────────────────────────────────────────────────────────\n\n/** What a picked title changes (D12): frontmatter `title:` wins, then the first H1, else a new H1. */\nexport type AiTitleEffect = 'frontmatter' | 'h1' | 'insertH1';\n\n/** The one-line hint under the candidates, naming the effect before the click. */\nexport const AI_TITLE_EFFECT_HINTS: Record<AiTitleEffect, string> = {\n frontmatter: 'Sets title: in Properties',\n h1: 'Replaces the H1',\n insertH1: 'Inserts an H1',\n};\n\n/** True when the frontmatter YAML has a top-level `title:` key. */\nexport function yamlHasTitle(yaml: string | null | undefined): boolean {\n return /^title[ \\t]*:/m.test(yaml ?? '');\n}\n\n/**\n * The YAML with its top-level `title:` set to `title` (quoted when YAML\n * needs it). Only the title entry changes, including any indented block\n * scalar lines under it; every other line stays byte-identical. Without a\n * `title:` key the YAML comes back unchanged.\n */\nexport function setYamlTitle(yaml: string, title: string): string {\n const lines = yaml.split('\\n');\n const i = lines.findIndex((l) => /^title[ \\t]*:/.test(l));\n if (i < 0) {return yaml;}\n let end = i + 1;\n while (end < lines.length && /^[ \\t]+\\S/.test(lines[end])) {end++;}\n lines.splice(i, end - i, `title: ${yamlScalar(title)}`);\n return lines.join('\\n');\n}\n\nfunction yamlScalar(s: string): string {\n const plain = !/[:#[\\]{},&*!|>'\"%@`]/.test(s) && !/^\\s|\\s$/.test(s) && !/^(-?\\d+(\\.\\d+)?|true|false|null|yes|no|on|off|~|-.*)$/i.test(s);\n return plain && s ? s : `\"${s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n}\n\n/**\n * Set the title in rich text in one transaction (its own undo step), removing\n * `remove` (a `/query`) in the same transaction: `h1` replaces the first\n * H1's text, `insertH1` puts a new H1 at the top. The frontmatter case is the\n * caller's (the YAML is not in the ProseMirror document).\n */\nexport function applyRichTitle(editor: Editor, effect: 'h1' | 'insertH1', title: string, remove?: { from: number; to: number } | null): boolean {\n if (editor.isDestroyed || !title.trim()) {return false;}\n const { schema } = editor.state;\n const heading = schema.nodes.heading;\n if (!heading) {return false;}\n const tr = closeHistory(editor.state.tr);\n if (remove && remove.to > remove.from) {tr.delete(remove.from, remove.to);}\n tr.setMeta(aiRewriteHighlightKey, { range: null });\n let h1: { pos: number; size: number } | null = null;\n if (effect === 'h1') {\n tr.doc.descendants((node, pos) => {\n if (h1) {return false;}\n if (node.type === heading && node.attrs.level === 1) {\n h1 = { pos, size: node.content.size };\n return false;\n }\n return !node.isTextblock;\n });\n }\n const found = h1 as { pos: number; size: number } | null;\n if (found) {\n tr.replaceWith(found.pos + 1, found.pos + 1 + found.size, schema.text(title));\n } else {\n tr.insert(0, heading.create({ level: 1 }, schema.text(title)));\n }\n editor.view.dispatch(tr.scrollIntoView());\n return true;\n}\n\n/** The first H1 line of `markdown` from `from` on (outside fenced code), or null. */\nfunction sourceH1Line(markdown: string, from: number): { from: number; to: number; prefix: string } | null {\n let pos = from;\n let fence: string | null = null;\n while (pos <= markdown.length) {\n const nl = markdown.indexOf('\\n', pos);\n const end = nl < 0 ? markdown.length : nl;\n const line = markdown.slice(pos, end);\n const f = /^ {0,3}(`{3,}|~{3,})/.exec(line);\n if (fence) {\n if (f && f[1][0] === fence[0] && f[1].length >= fence.length && !line.trim().slice(f[1].length).trim()) {fence = null;}\n } else if (f) {\n fence = f[1];\n } else {\n const m = /^( {0,3}#[ \\t]+)/.exec(line);\n if (m) {return { from: pos, to: end, prefix: m[1] };}\n }\n if (nl < 0) {break;}\n pos = nl + 1;\n }\n return null;\n}\n\n/**\n * Set the title in source mode in one CM transaction: the frontmatter\n * `title:` line, else the first H1's text, else a new H1 at the start of the\n * body (`bodyStart`).\n */\nexport function applySourceTitle(view: CmEditorView, effect: AiTitleEffect, title: string, frontmatter: { yaml: string | null; bodyStart: number }): boolean {\n if (!title.trim()) {return false;}\n const full = view.state.doc.toString();\n let change: { from: number; to: number; insert: string };\n if (effect === 'frontmatter' && frontmatter.yaml !== null && yamlHasTitle(frontmatter.yaml)) {\n // The YAML sits between the opening `---` line and the closing one.\n const yamlFrom = full.indexOf('\\n') + 1;\n change = { from: yamlFrom, to: yamlFrom + frontmatter.yaml.length, insert: setYamlTitle(frontmatter.yaml, title) };\n } else {\n const h1 = effect === 'insertH1' ? null : sourceH1Line(full, frontmatter.bodyStart);\n change = h1\n ? { from: h1.from + h1.prefix.length, to: h1.to, insert: title }\n : { from: frontmatter.bodyStart, to: frontmatter.bodyStart, insert: `# ${title}\\n\\n` };\n }\n view.dispatch({\n changes: change,\n effects: setCmRewriteRange.of(null),\n annotations: isolateHistory.of('full'),\n userEvent: 'input.ai',\n });\n return true;\n}\n\n// ── Icons ───────────────────────────────────────────────────────────────────\n\nconst icon = (body: string, size = 14) => `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${body}</svg>`;\nconst SPARK = icon('<path d=\"M8 2.2l1.25 3.3 3.3 1.25-3.3 1.25L8 11.3 6.75 8 3.45 6.75 6.75 5.5z\"/><path d=\"M12.6 10.6l.5 1.3 1.3.5-1.3.5-.5 1.3-.5-1.3-1.3-.5 1.3-.5z\"/>');\nconst CLOSE = icon('<path d=\"M4.5 4.5l7 7M11.5 4.5l-7 7\"/>', 12);\nconst LOCAL = icon('<path d=\"M2.5 7.5L8 3l5.5 4.5M4 6.5V13h8V6.5\"/>', 11);\nconst CLOUD = icon('<path d=\"M4.5 12.5h7a2.75 2.75 0 0 0 .3-5.48A4 4 0 0 0 4.1 7.6 2.5 2.5 0 0 0 4.5 12.5z\"/>', 11);\nconst ALERT = icon('<path d=\"M8 2.5l6 10.5H2z\"/><path d=\"M8 6.5v3M8 11.4v.1\"/>', 16);\nconst WARN = icon('<path d=\"M8 2.5l6 10.5H2z\"/><path d=\"M8 6.5v3M8 11.4v.1\"/>', 12);\nconst BACK = icon('<path d=\"M9.5 4L5.5 8l4 4\"/>', 14);\nconst CHECK = icon('<path d=\"M3.5 8.5l3 3 6-7\"/>', 12);\n\nfunction el<K extends keyof HTMLElementTagNameMap>(tag: K, className?: string, text?: string): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n if (className) {node.className = className;}\n if (text !== undefined) {node.textContent = text;}\n return node;\n}\n\nfunction button(className: string, label: string, onClick: () => void): HTMLButtonElement {\n const b = el('button', className, label);\n b.type = 'button';\n // Keep the editor's selection and focus where they are until the action runs.\n b.addEventListener('mousedown', (e) => e.preventDefault());\n b.addEventListener('click', () => { if (b.getAttribute('aria-disabled') !== 'true') {onClick();} });\n return b;\n}\n\nexport function isMacPlatform(): boolean {\n return typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || '');\n}\n\n// ── Grouped variants ────────────────────────────────────────────────────────\n\nconst GROUP_LABELS: Record<AiRewriteGroup, string> = {\n length: 'Length',\n tone: 'Tone',\n audience: 'Audience',\n translate: 'Translate',\n explain: 'Explain',\n custom: 'Custom',\n};\n\nexport interface AiRewriteMenuGroup {\n group: AiRewriteGroup;\n label: string;\n variants: AiRewriteVariantDefinition[];\n}\n\n/** `AI_REWRITE_VARIANTS` in menu order, one entry per group (Length, Tone, …, Custom). */\nexport function aiRewriteMenuGroups(): AiRewriteMenuGroup[] {\n const groups: AiRewriteMenuGroup[] = [];\n for (const v of AI_REWRITE_VARIANTS) {\n let g = groups.find((x) => x.group === v.group);\n if (!g) {\n g = { group: v.group, label: GROUP_LABELS[v.group], variants: [] };\n groups.push(g);\n }\n g.variants.push(v);\n }\n return groups;\n}\n\n/** Variants whose result is checked for dropped links, code, list items and the like. */\nconst STRUCTURE_CHECKED = new Set<AiRewriteVariant>(['translate', 'simpler', 'formal', 'casual', 'expand']);\n\nconst STRUCTURE_NOUNS: Record<StructureMismatch['kind'], [string, string]> = {\n heading: ['heading', 'headings'],\n fencedCodeBlock: ['code block', 'code blocks'],\n inlineCode: ['inline code span', 'inline code spans'],\n link: ['link', 'links'],\n image: ['image', 'images'],\n listItem: ['list item', 'list items'],\n tableRow: ['table row', 'table rows'],\n wikilink: ['wikilink', 'wikilinks'],\n footnote: ['footnote reference', 'footnote references'],\n};\n\n/**\n * The warning line for a structure diff (\"Check: 1 link missing in the\n * result\"), or '' when nothing differs. Headings of every level count as one.\n */\nexport function structureWarningText(diff: StructureDiff): string {\n if (diff.ok) {return '';}\n const byKind = new Map<StructureMismatch['kind'], { original: number; result: number; message: string }>();\n for (const m of diff.mismatches) {\n const seen = byKind.get(m.kind);\n if (seen) {\n seen.original += m.original;\n seen.result += m.result;\n } else {\n byKind.set(m.kind, { original: m.original, result: m.result, message: m.message });\n }\n }\n const parts: string[] = [];\n for (const [kind, m] of byKind) {\n const [one, many] = STRUCTURE_NOUNS[kind];\n const d = m.original - m.result;\n const noun = Math.abs(d) === 1 ? one : many;\n if (d > 0) {parts.push(`${d} ${noun} missing in the result`);}\n else if (d < 0) {parts.push(`${-d} extra ${noun} in the result`);}\n else if (kind === 'link' || kind === 'image') {parts.push(`${many} point somewhere else in the result`);}\n else {parts.push(`${many} differ in the result`);}\n }\n return `Check: ${parts.join('; ')}`;\n}\n\n/**\n * Output budget for a whole-document translation: about the body's length\n * again, more than `rewriteMaxTokens` allows a selection. A host that cannot\n * take it answers `contextOverflow` or stops at the length limit.\n */\nfunction documentMaxTokens(text: string): number {\n return Math.max(1024, Math.min(16384, Math.ceil((text.length / CHARS_PER_TOKEN) * 1.6) + 256));\n}\n\n/** Tokens kept for the system prompt, the instructions and slack around a budgeted document. */\nconst DOCUMENT_RESERVE_TOKENS = 768;\n\n/**\n * Fit a whole-document translation to the model's context. The answer is\n * about as long as what is sent, so when the body does not fit beside its\n * own `documentMaxTokens` the context is split: about 1 part sent to 1.6\n * parts answer. Returns the part to send, the output budget and what is left.\n */\nexport function budgetTranslation(body: string, contextTokens: number): { text: string; rest: string; coverage: number; maxTokens: number } {\n let maxTokens = documentMaxTokens(body);\n let b = budgetDocument(body, { contextTokens, outputTokens: maxTokens, reserveTokens: DOCUMENT_RESERVE_TOKENS });\n if (b.truncated) {\n const room = Math.max(0, contextTokens - DOCUMENT_RESERVE_TOKENS);\n maxTokens = Math.max(1024, Math.min(16384, Math.floor((room * 1.6) / 2.6)));\n b = budgetDocument(body, { contextTokens, outputTokens: maxTokens, reserveTokens: DOCUMENT_RESERVE_TOKENS });\n if (b.truncated) {maxTokens = Math.min(maxTokens, documentMaxTokens(b.text));}\n }\n return b.truncated\n ? { text: b.text, rest: body.slice(b.text.length), coverage: b.coverage, maxTokens }\n : { text: body, rest: '', coverage: 1, maxTokens };\n}\n\n/** The coverage line for a budgeted document job, or '' when all of it was sent. */\nexport function coverageNoteText(job: 'summary' | 'titles' | 'translate', coverage: number): string {\n if (coverage >= 1) {return '';}\n const pct = coveragePercent(coverage);\n if (job === 'translate') {return `Translates the first ${pct}% of the document; the rest did not fit the model's context and stays as it is.`;}\n if (job === 'titles') {return `Based on the first ${pct}% of the document and all of its headings; the rest did not fit the model's context.`;}\n return `Covers the first ${pct}% of the document; the rest did not fit the model's context.`;\n}\n\n// ── Popover ─────────────────────────────────────────────────────────────────\n\nexport interface AiRewriteBadge {\n where: 'local' | 'cloud' | null;\n text: string;\n title: string;\n fallback: boolean;\n}\n\nexport interface AiRewritePopoverDeps {\n run(req: AiRunRequest, events: AiRunEvents, signal: AbortSignal): Promise<AiRunOutcome>;\n /** Footer badge for the route about to serve (before the result) or what served. */\n badge(route: AiRouteOk | null, served: AiServedBy | null, viaFallback: boolean, about?: { feature?: string; sends?: AiSendsScope }): AiRewriteBadge | null;\n onServed(served: AiServedBy, viaFallback: boolean): void;\n /** The AI settings; with `engineId`, that engine's page (an error's \"Open <engine>\"). */\n openSettings(engineId?: string): void;\n /** An engine's display name, so an error can name it (\"Anthropic refused the API key.\"). Absent: errors stay generic. */\n engineName?(engineId: string): string | null;\n /** A request started or stopped running in the popover (the toolbar button's running state). */\n onBusy?(running: boolean): void;\n /** The whole body as a target (Translate's \"Whole document\"); absent hides the toggle. */\n documentTarget?(): AiRewriteTarget | null;\n /**\n * The routed model for `feature`, before sending: its context window (null\n * when unknown, then `DEFAULT_CONTEXT_TOKENS`) and whether it has a JSON\n * mode. Absent: the defaults.\n */\n routeInfo?(feature: string): { contextTokens: number | null; json: boolean };\n}\n\n/** `/summary` and `/outline`: what to summarise. */\nexport interface AiSummaryJob {\n /** The document body as markdown (frontmatter left out). */\n markdown: string;\n kind: AiSummaryKind;\n}\n\n/** `/title`: what to title, and what a pick does. */\nexport interface AiTitleJob {\n /** The document body as markdown (frontmatter left out). */\n markdown: string;\n /** The current title, so the model does not hand it back. */\n existingTitle?: string;\n /** What a pick changes; named in the hint under the list. */\n effect: AiTitleEffect;\n /** Set the picked title (one undo step). False when nothing changed. */\n apply(title: string): boolean;\n}\n\n/** What to run when the popover opens; a parameterised variant without its parameter opens its picker. */\nexport interface AiRewriteChoice {\n variant: AiRewriteVariant;\n instruction?: string;\n params?: AiRewriteParams;\n /** Translate the whole document instead of the selection. */\n wholeDocument?: boolean;\n}\n\nexport interface AiRewritePopover {\n /** Open on a target: with a variant it runs at once (or opens its picker), without one it shows the choices. */\n open(target: AiRewriteTarget, choice?: AiRewriteChoice): void;\n /** Open on a target to say why rewrite cannot run (AI on, no usable route). */\n openUnavailable(target: AiRewriteTarget, reason: string): void;\n /** `insert` mode: summarise the document and insert the block at the target. */\n openSummary(target: AiRewriteTarget, job: AiSummaryJob): void;\n /** `choose` mode: suggest three titles; a click applies one. */\n openTitles(target: AiRewriteTarget, job: AiTitleJob): void;\n close(): void;\n isOpen(): boolean;\n destroy(): void;\n}\n\ntype Phase = 'choose' | 'running' | 'done' | 'error';\ntype Picker = 'language' | 'audience';\ntype OutputMode = 'replace' | 'readOnly' | 'replaceDocument' | 'insert' | 'choose';\n/** What the popover is running: a rewrite variant, a summary, or title suggestions. */\ntype Job = 'rewrite' | 'summary' | 'titles';\n\nconst SUMMARY_KIND_LABELS: Record<AiSummaryKind, string> = { tldr: 'TL;DR', outline: 'Outline' };\nconst REPAIR_NOTE = 'Fixing the answer format…';\n\n/** True when `params` holds what `def` needs. */\nfunction hasParam(def: AiRewriteVariantDefinition | undefined, params: AiRewriteParams): boolean {\n if (def?.param === 'language') {return !!params.language?.trim();}\n if (def?.param === 'audience') {return !!params.audience && !!getAiAudience(params.audience);}\n return true;\n}\n\nconst plainLabel = (label: string): string => label.replace(/…$/, '');\n\n/** The dial's segment label: `thinkingChoices` labels, Medium shortened to fit the header. */\nconst thinkingSegmentLabel = (label: string): string => (label === 'Medium' ? 'Med' : label);\n\n/** The level a route ran with: what the request sent, else the model's own. */\nfunction thinkingInEffect(t: AiRunThinking | null): AiThinkingLevel | null {\n return t ? t.sent ?? t.configured : null;\n}\n\n/** The dial's Default segment: MikeDown picks per task (Off for short edits), else no thinking fields. */\nconst THINKING_DEFAULT = 'default';\n\n/** The remembered preference the dial shows as checked: the level sent, else Default (also when the job's default was sent). */\nconst thinkingSelected = (t: AiRunThinking | null): string => (t && !t.auto ? t.sent : null) ?? THINKING_DEFAULT;\n\n/** \"local · Proxy · model\" reads \"Local · Proxy · model\". */\nconst capitalizeFirst = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);\n\nexport function createAiRewritePopover(deps: AiRewritePopoverDeps): AiRewritePopover {\n let target: AiRewriteTarget | null = null;\n let root: HTMLElement | null = null;\n let phase: Phase = 'choose';\n let variant: AiRewriteVariant = 'shorter';\n let instruction = '';\n let params: AiRewriteParams = {};\n let picker: Picker | null = null;\n let wholeDocument = false;\n /** Opened on the document itself (no selection): only the language picker applies. */\n let docOnly = false;\n let controller: AbortController | null = null;\n let runSeq = 0;\n let raw = '';\n let finalText = '';\n /** The summary stream stopped at the length limit: the preview drops the same fragment Insert does. */\n let summaryCutOff = false;\n let route: AiRouteOk | null = null;\n let served: AiServedBy | null = null;\n /** How long the served result took and how fast it came (null: the host did not measure). */\n let stats: AiResultStats | null = null;\n let viaFallback = false;\n /** The thinking dial for the current route; null hides it (no mapping, tier-1 host, no route yet). */\n let thinking: AiRunThinking | null = null;\n let error: AiError | null = null;\n /** Copy that replaces the error code's own (an answer that never came, out of room). */\n let errorCopy: AiErrorCopy | null = null;\n /** The error is the router's: nothing can serve, so the fix is in settings. */\n let unavailable = false;\n let note = '';\n let warning: { text: string; title: string } | null = null;\n let job: Job = 'rewrite';\n let summaryJob: AiSummaryJob | null = null;\n let titleJob: AiTitleJob | null = null;\n let titles: string[] = [];\n /** Share of the document sent (summary, titles, whole-document translate); 1 when all of it fit. */\n let coverage = 1;\n /** What the rewrite was asked about: the selection, or the part of the body that fit. */\n let sentText = '';\n /** A whole-document translation cut to fit: the rest of the body, kept as it is on Accept. */\n let untranslated = '';\n /** The title job's JSON repair round trip is running (D16). */\n let repairing = false;\n let side: 'below' | 'above' | null = null;\n let frame = 0;\n let copiedTimer: number | undefined;\n let detach: Array<() => void> = [];\n\n // Parts rebuilt per open.\n let titleEl: HTMLElement;\n let badgeEl: HTMLElement;\n let statsEl: HTMLElement;\n let thinkEl: HTMLElement;\n let chooseEl: HTMLElement;\n let menuEl: HTMLElement;\n let formEl: HTMLFormElement;\n let pickerEl: HTMLElement;\n let inputEl: HTMLInputElement;\n let bodyEl: HTMLElement;\n let oldTextEl: HTMLElement;\n let outEl: HTMLElement;\n let caretEl: HTMLElement;\n let newLabelEl: HTMLElement;\n let newPaneEl: HTMLElement;\n let errorEl: HTMLElement;\n let warnEl: HTMLElement;\n let footEl: HTMLElement;\n let acceptBtn: HTMLButtonElement;\n let retryBtn: HTMLButtonElement;\n let copyBtn: HTMLButtonElement;\n let noteEl: HTMLElement;\n let closeBtn: HTMLButtonElement;\n let liveEl: HTMLElement;\n let kindEl: HTMLElement;\n let coverageEl: HTMLElement;\n let titlesBoxEl: HTMLElement;\n let titlesEl: HTMLElement;\n let titleHintEl: HTMLElement;\n\n function abort(): void {\n runSeq += 1;\n controller?.abort();\n controller = null;\n }\n\n function close(opts: { refocus?: boolean } = {}): void {\n if (!target) {return;}\n abort();\n cancelAnimationFrame(frame);\n window.clearTimeout(copiedTimer);\n for (const off of detach) {off();}\n detach = [];\n root?.remove();\n root = null;\n syncBusy();\n const t = target;\n target = null;\n picker = null;\n t.release();\n if (opts.refocus !== false) {t.focus();}\n }\n\n function outputMode(): OutputMode {\n if (job === 'summary') {return 'insert';}\n if (job === 'titles') {return 'choose';}\n if (getAiRewriteVariant(variant)?.output === 'readOnly') {return 'readOnly';}\n return target?.scope === 'document' ? 'replaceDocument' : 'replace';\n }\n\n function build(): HTMLElement {\n const box = el('div', 'mikedown-ai-rewrite');\n box.setAttribute('role', 'dialog');\n box.setAttribute('aria-label', 'Rewrite with AI');\n box.tabIndex = -1;\n\n const head = el('div', 'ai-rw-head');\n const spark = el('span', 'ai-rw-spark');\n spark.innerHTML = SPARK;\n titleEl = el('span', 'ai-rw-title', 'Rewrite');\n thinkEl = el('div', 'ai-rw-think');\n thinkEl.setAttribute('role', 'radiogroup');\n thinkEl.setAttribute('aria-label', 'Thinking');\n thinkEl.hidden = true;\n // Arrow keys move between levels (roving focus); Enter or Space picks, which runs again.\n thinkEl.addEventListener('keydown', onThinkingKey);\n badgeEl = el('span', 'ai-rw-badge');\n badgeEl.hidden = true;\n closeBtn = button('ai-rw-icon-btn', '', () => close());\n closeBtn.innerHTML = CLOSE;\n // TL;DR ⇄ Outline for a summary; picking the other one runs again.\n kindEl = el('div', 'ai-rw-kind');\n kindEl.setAttribute('role', 'group');\n kindEl.setAttribute('aria-label', 'Summary kind');\n kindEl.hidden = true;\n for (const k of ['tldr', 'outline'] as const) {\n const seg = button('ai-rw-kind-seg', SUMMARY_KIND_LABELS[k], () => pickKind(k));\n seg.dataset.kind = k;\n seg.title = k === 'tldr' ? 'A short TL;DR of the document (runs again)' : 'An outline of the document (runs again)';\n kindEl.append(seg);\n }\n // The title and the thinking dial; the engine badge is in the footer, where it has room.\n head.append(spark, titleEl, kindEl, thinkEl, closeBtn);\n\n // First level: one row per group (Length, Tone, Audience, Translate,\n // Explain), then the custom prompt. Second level: the picker.\n chooseEl = el('div', 'ai-rw-choose');\n menuEl = el('div', 'ai-rw-menu');\n menuEl.setAttribute('role', 'menu');\n menuEl.setAttribute('aria-label', 'Rewrite options');\n for (const g of aiRewriteMenuGroups()) {\n if (g.group === 'custom') {continue;}\n const section = el('div', 'ai-rw-group');\n section.dataset.group = g.group;\n section.setAttribute('role', 'group');\n section.setAttribute('aria-label', g.label);\n const heading = el('div', 'ai-rw-group-label', g.label);\n heading.setAttribute('aria-hidden', 'true');\n const chips = el('div', 'ai-rw-chips');\n for (const v of g.variants) {\n const chip = button('ai-rw-chip', v.label, () => choose(v));\n chip.setAttribute('role', 'menuitem');\n if (v.title) {chip.title = v.title;}\n chip.dataset.variant = v.id;\n if (v.param) {chip.setAttribute('aria-haspopup', 'menu');}\n chips.append(chip);\n }\n section.append(heading, chips);\n menuEl.append(section);\n }\n formEl = el('form', 'ai-rw-form');\n inputEl = el('input', 'ai-rw-input');\n inputEl.type = 'text';\n inputEl.placeholder = 'Describe a change, e.g. \"make it friendlier\"';\n inputEl.setAttribute('aria-label', 'Custom rewrite instruction');\n inputEl.maxLength = 1000;\n const go = button('ai-rw-btn ai-rw-btn--primary', 'Rewrite', () => submitCustom());\n formEl.append(inputEl, go);\n formEl.addEventListener('submit', (e) => { e.preventDefault(); submitCustom(); });\n pickerEl = el('div', 'ai-rw-picker');\n chooseEl.append(menuEl, formEl, pickerEl);\n\n bodyEl = el('div', 'ai-rw-body');\n const oldPane = el('div', 'ai-rw-pane ai-rw-pane--old');\n oldTextEl = el('div', 'ai-rw-text');\n oldPane.append(el('div', 'ai-rw-label', 'Original'), oldTextEl);\n newPaneEl = el('div', 'ai-rw-pane ai-rw-pane--new');\n const newText = el('div', 'ai-rw-text');\n outEl = el('div', 'ai-rw-out');\n caretEl = el('span', 'ai-rw-caret');\n newText.append(outEl);\n newLabelEl = el('div', 'ai-rw-label', 'Rewrite');\n newPaneEl.append(newLabelEl, newText);\n bodyEl.append(oldPane, newPaneEl);\n\n // Title candidates, and what a pick changes.\n titlesBoxEl = el('div', 'ai-rw-titles-box');\n titlesEl = el('div', 'ai-rw-titles');\n titlesEl.setAttribute('role', 'menu');\n titlesEl.setAttribute('aria-label', 'Suggested titles');\n titleHintEl = el('div', 'ai-rw-titles-hint');\n titlesBoxEl.append(titlesEl, titleHintEl);\n\n errorEl = el('div', 'ai-rw-error');\n errorEl.setAttribute('role', 'alert');\n\n coverageEl = el('div', 'ai-rw-coverage');\n\n warnEl = el('div', 'ai-rw-warn');\n\n footEl = el('div', 'ai-rw-foot');\n acceptBtn = button('ai-rw-btn ai-rw-btn--primary', 'Accept', () => accept());\n retryBtn = button('ai-rw-btn', 'Retry', () => rerun());\n copyBtn = button('ai-rw-btn', 'Copy', () => copy());\n noteEl = el('span', 'ai-rw-note');\n // \"2.4 s · 38 tok/s\", beside the badge once the answer is in.\n statsEl = el('span', 'ai-rw-stats');\n statsEl.hidden = true;\n footEl.append(acceptBtn, retryBtn, copyBtn, noteEl, statsEl, badgeEl);\n\n liveEl = el('div', 'ai-rw-sr');\n liveEl.setAttribute('aria-live', 'polite');\n\n box.append(head, chooseEl, bodyEl, titlesBoxEl, errorEl, coverageEl, warnEl, footEl, liveEl);\n return box;\n }\n\n function submitCustom(): void {\n const text = inputEl.value.trim();\n if (!text) { inputEl.focus(); return; }\n start('custom', text);\n }\n\n /** A first-level choice: a parameterised variant opens its picker, the rest run. */\n function choose(def: AiRewriteVariantDefinition): void {\n if (def.param) {\n openPicker(def.param === 'language' ? 'language' : 'audience');\n return;\n }\n start(def.id);\n }\n\n // ── Second-level pickers ───────────────────────────────────────────────\n\n function pickerOption(label: string, checked: boolean, onPick: () => void): HTMLButtonElement {\n const b = button('ai-rw-option', '', onPick);\n b.setAttribute('role', 'menuitemradio');\n b.setAttribute('aria-checked', checked ? 'true' : 'false');\n const mark = el('span', 'ai-rw-option-check');\n mark.innerHTML = CHECK;\n b.append(mark, el('span', 'ai-rw-option-label', label));\n return b;\n }\n\n function pickerSeparator(): HTMLElement {\n const sep = el('div', 'ai-rw-option-sep');\n sep.setAttribute('role', 'separator');\n return sep;\n }\n\n function renderPicker(): void {\n if (!picker) { pickerEl.replaceChildren(); return; }\n const head = el('div', 'ai-rw-picker-head');\n const back = button('ai-rw-icon-btn ai-rw-back', '', () => closePicker());\n back.innerHTML = BACK;\n back.setAttribute('aria-label', 'Back (Esc)');\n back.title = 'Back (Esc)';\n back.hidden = docOnly;\n head.append(back, el('span', 'ai-rw-picker-title', picker === 'language' ? 'Translate to' : 'Reading level'));\n\n const list = el('div', 'ai-rw-picker-list');\n list.setAttribute('role', 'menu');\n list.setAttribute('aria-label', picker === 'language' ? 'Language' : 'Audience');\n const parts: HTMLElement[] = [head, list];\n\n if (picker === 'language') {\n const { recents, languages } = translateLanguageChoices();\n // The last language used is the default: checked and focused.\n recents.forEach((lang, i) => list.append(pickerOption(lang, i === 0, () => pickLanguage(lang))));\n if (recents.length) {list.append(pickerSeparator());}\n for (const lang of languages) {list.append(pickerOption(lang, false, () => pickLanguage(lang)));}\n list.append(pickerSeparator());\n const otherForm = el('form', 'ai-rw-form ai-rw-other');\n otherForm.hidden = true;\n const otherInput = el('input', 'ai-rw-input');\n otherInput.type = 'text';\n otherInput.placeholder = 'Language, e.g. Swahili';\n otherInput.setAttribute('aria-label', 'Other language');\n otherInput.maxLength = 60;\n otherForm.append(otherInput, button('ai-rw-btn ai-rw-btn--primary', 'Translate', () => pickLanguage(otherInput.value)));\n otherForm.addEventListener('submit', (e) => { e.preventDefault(); pickLanguage(otherInput.value); });\n const other = button('ai-rw-option ai-rw-option--other', '', () => {\n otherForm.hidden = false;\n other.setAttribute('aria-expanded', 'true');\n otherInput.focus();\n position();\n });\n other.setAttribute('role', 'menuitem');\n other.setAttribute('aria-expanded', 'false');\n other.append(el('span', 'ai-rw-option-check'), el('span', 'ai-rw-option-label', 'Other…'));\n list.append(other);\n parts.push(otherForm);\n\n if (docOnly || deps.documentTarget) {\n const toggle = el('label', 'ai-rw-toggle');\n const box = el('input');\n box.type = 'checkbox';\n box.checked = wholeDocument;\n box.disabled = docOnly;\n box.addEventListener('change', () => { wholeDocument = box.checked; });\n toggle.append(box, el('span', '', 'Whole document'));\n toggle.title = docOnly ? 'Nothing is selected, so the whole document is translated.' : 'Translate the whole document instead of the selection (frontmatter is kept).';\n const foot = el('div', 'ai-rw-picker-foot');\n foot.append(toggle);\n parts.push(foot);\n }\n } else {\n const remembered = loadAudience();\n for (const a of AI_AUDIENCES) {list.append(pickerOption(a.label, a.id === remembered, () => pickAudience(a.id)));}\n }\n pickerEl.replaceChildren(...parts);\n }\n\n function openPicker(kind: Picker): void {\n picker = kind;\n variant = kind === 'language' ? 'translate' : 'readingLevel';\n phase = 'choose';\n renderPicker();\n render();\n position();\n const items = [...pickerEl.querySelectorAll<HTMLButtonElement>('.ai-rw-picker-list > button')];\n (items.find((b) => b.getAttribute('aria-checked') === 'true') ?? items[0])?.focus({ preventScroll: true });\n }\n\n function closePicker(): void {\n if (docOnly) { close(); return; }\n const was = variant;\n picker = null;\n renderPicker();\n render();\n position();\n menuEl.querySelector<HTMLButtonElement>(`.ai-rw-chip[data-variant=\"${was}\"]`)?.focus({ preventScroll: true });\n }\n\n function pickLanguage(language: string): void {\n const lang = language.replace(/\\s+/g, ' ').trim();\n if (!lang) {\n pickerEl.querySelector<HTMLInputElement>('.ai-rw-other .ai-rw-input')?.focus();\n return;\n }\n params = { language: lang };\n if (wholeDocument && !useDocumentTarget()) {return;}\n start('translate');\n }\n\n function pickAudience(audience: AiAudience): void {\n params = { audience };\n start('readingLevel');\n }\n\n /** Swap the selection target for the whole body. False when there is no body to translate. */\n function useDocumentTarget(): boolean {\n if (!target) {return false;}\n if (target.scope === 'document') {return true;}\n const doc = deps.documentTarget?.() ?? null;\n if (!doc) {return false;}\n target.release();\n target = doc;\n side = null;\n return true;\n }\n\n // ── Rendering ──────────────────────────────────────────────────────────\n\n function headTitle(): string {\n if (job === 'summary') {return summaryJob?.kind === 'outline' ? 'Outline' : 'Summary';}\n if (job === 'titles') {return 'Suggest titles';}\n if (unavailable) {return 'Rewrite';}\n if (phase === 'choose') {return picker === 'language' ? 'Translate' : picker === 'audience' ? 'Reading level' : 'Rewrite';}\n if (variant === 'explain') {return 'Explain';}\n if (variant === 'custom') {return 'Rewrite · Custom';}\n if (variant === 'translate') {\n return `Translate · ${params.language ?? ''}${target?.scope === 'document' ? ' · Whole document' : ''}`;\n }\n if (variant === 'readingLevel') {\n return `Reading level · ${(params.audience && getAiAudience(params.audience)?.label) ?? ''}`;\n }\n return `Rewrite · ${plainLabel(getAiRewriteVariant(variant)?.label ?? '')}`;\n }\n\n /**\n * The thinking dial: a radio group with one segment per level the route's\n * kind can express, the level in effect checked. One Tab stop; a redraw\n * keeps the focus on the segment that had it.\n */\n function renderThinking(): void {\n const choices = thinking && phase !== 'choose' ? thinkingChoices(thinking.kind) : [];\n thinkEl.hidden = choices.length === 0;\n if (choices.length === 0) {return;}\n const current = thinkingSelected(thinking);\n const focused = thinkEl.contains(document.activeElement) ? (document.activeElement as HTMLElement).dataset.level : undefined;\n const label = el('span', 'ai-rw-think-label', 'Thinking');\n label.setAttribute('aria-hidden', 'true');\n // The AI menu's Thinking row: Default first (MikeDown picks per task, else the model's own setting), then the kind's levels.\n const options = [\n { level: THINKING_DEFAULT, label: 'Default', title: 'Thinking: picked for the task' },\n ...choices.map((c) => ({ level: c.level as string, label: thinkingSegmentLabel(c.label), title: `Thinking: ${c.label}` })),\n ];\n const stop = focused && options.some((o) => o.level === focused) ? focused : current;\n const segments = options.map((o) => {\n const seg = button('ai-rw-think-seg', o.label, () => pickThinking(o.level === THINKING_DEFAULT ? null : o.level as AiThinkingLevel));\n seg.dataset.level = o.level;\n seg.setAttribute('role', 'radio');\n seg.setAttribute('aria-checked', o.level === current ? 'true' : 'false');\n seg.setAttribute('aria-label', o.level === THINKING_DEFAULT ? 'Default' : choices.find((c) => c.level === o.level)?.label ?? o.label);\n seg.tabIndex = o.level === stop ? 0 : -1;\n seg.title = `${o.title} (runs again)`;\n return seg;\n });\n const effective = thinkingInEffect(thinking);\n thinkEl.title = thinking?.sent && thinking.auto\n ? `Thinking: Default, ${choices.find((c) => c.level === thinking?.sent)?.label ?? thinking.sent} for this task`\n : thinking?.sent\n ? `Thinking: ${choices.find((c) => c.level === thinking?.sent)?.label ?? thinking.sent}`\n : effective\n ? `Thinking: the model's setting (${choices.find((c) => c.level === effective)?.label ?? effective})`\n : 'Thinking: the model\\'s default';\n thinkEl.replaceChildren(label, ...segments);\n if (focused) {segments.find((b) => b.dataset.level === focused)?.focus({ preventScroll: true });}\n }\n\n function onThinkingKey(e: KeyboardEvent): void {\n if (!/^(Arrow(Left|Right|Up|Down)|Home|End)$/.test(e.key)) {return;}\n const segs = [...thinkEl.querySelectorAll<HTMLButtonElement>('.ai-rw-think-seg')];\n const at = segs.indexOf(document.activeElement as HTMLButtonElement);\n if (at < 0) {return;}\n e.preventDefault();\n e.stopPropagation();\n const forward = e.key === 'ArrowRight' || e.key === 'ArrowDown';\n const next = e.key === 'Home' ? 0 : e.key === 'End' ? segs.length - 1 : (at + (forward ? 1 : -1) + segs.length) % segs.length;\n for (const [i, b] of segs.entries()) {b.tabIndex = i === next ? 0 : -1;}\n segs[next].focus({ preventScroll: true });\n }\n\n function renderBadge(): void {\n renderThinking();\n const b = deps.badge(route, served, served ? viaFallback : route?.viaFallback ?? false, jobSends());\n badgeEl.hidden = !b;\n if (!b) {return;}\n badgeEl.dataset.where = b.where ?? '';\n badgeEl.classList.toggle('is-pending', !served);\n // Name the level that served (\"... oMLX · Qwen3 30B, on this network. Thinking: low.\").\n const level = served ? thinkingInEffect(thinking) : null;\n const levelLabel = level && thinking ? thinkingChoices(thinking.kind).find((c) => c.level === level)?.label : undefined;\n let title = b.title;\n if (b.where === 'cloud') {\n // What leaves the machine, unless the host's title already says it.\n const j = jobSends();\n const what = whatIsSent(j.feature, j.sends);\n if (!title.includes(what)) {title = `${title} ${served ? 'Sent' : 'Sends'} ${what}.`;}\n }\n badgeEl.title = levelLabel ? `${title} Thinking: ${levelLabel.toLowerCase()}.` : title;\n const glyph = el('span', 'ai-rw-badge-glyph');\n glyph.innerHTML = b.where === 'cloud' ? CLOUD : LOCAL;\n // \"local · oMLX · Qwen3 30B\": locality and engine never shrink, only the model name ellipsizes.\n const text = el('span', 'ai-rw-badge-text');\n const cut = capitalizeFirst(b.text).split(' · ');\n if (cut.length >= 3) {\n text.append(el('span', 'ai-rw-badge-engine', `${cut.slice(0, 2).join(' · ')} · `), el('span', 'ai-rw-badge-model', cut.slice(2).join(' · ')));\n } else {\n text.append(el('span', 'ai-rw-badge-engine', capitalizeFirst(b.text)));\n }\n const parts: Node[] = [glyph, text];\n if (b.fallback) {parts.push(el('span', 'ai-rw-badge-fallback', '(fallback)'));}\n badgeEl.replaceChildren(...parts);\n }\n\n /** The caret follows the last line of the preview rather than sitting under a block. */\n function placeCaret(): void {\n let host: Element = outEl;\n for (let last = host.lastElementChild; last && /^(UL|OL|LI|BLOCKQUOTE|P|DIV)$/.test(last.tagName); last = host.lastElementChild) {host = last;}\n host.append(caretEl);\n }\n\n function renderOut(): void {\n // Titles stream as JSON: only a placeholder until the list shows.\n const shown = job === 'titles' ? ''\n : job === 'summary' ? (phase === 'done' && summaryJob ? summaryPreviewText(raw, summaryJob.kind, summaryCutOff) : summaryVisibleText(raw)).trim()\n : phase === 'done' ? finalText.trim() : rewriteVisibleText(raw).trimStart();\n renderPreviewMarkdown(outEl, shown);\n placeCaret();\n newPaneEl.classList.toggle('is-waiting', phase === 'running' && !shown);\n if (phase === 'running' && !shown) {\n const name = deps.badge(route, null, false)?.text.split(' · ')[1];\n outEl.replaceChildren();\n placeCaret();\n outEl.dataset.placeholder = repairing ? REPAIR_NOTE\n : job === 'titles' && raw ? 'Suggesting titles…'\n : name ? `Waiting for ${name}…` : 'Waiting for the engine…';\n } else {\n delete outEl.dataset.placeholder;\n }\n // Follow the stream unless the reader scrolled up.\n const scroller = outEl.parentElement;\n if (scroller && phase === 'running' && scroller.scrollHeight - scroller.scrollTop - scroller.clientHeight < 40) {\n scroller.scrollTop = scroller.scrollHeight;\n }\n }\n\n function scheduleOut(): void {\n if (frame) {return;}\n frame = requestAnimationFrame(() => { frame = 0; if (root) {renderOut();} });\n }\n\n /** Tell the host when a request starts or stops running here (once per change). */\n let busyReported = false;\n function syncBusy(): void {\n const running = !!root && phase === 'running';\n if (running === busyReported) {return;}\n busyReported = running;\n deps.onBusy?.(running);\n }\n\n function render(): void {\n syncBusy();\n if (!root || !target) {return;}\n const mode = outputMode();\n root.dataset.phase = phase;\n root.dataset.output = mode;\n // Side by side only for a multi-line selection being replaced: not for\n // Explain (nothing is replaced) nor a whole document (too long).\n root.dataset.layout = mode === 'replace' && target.multiline ? 'split' : 'single';\n root.setAttribute('aria-busy', phase === 'running' ? 'true' : 'false');\n root.setAttribute('aria-label', job === 'summary' ? 'Summarize with AI'\n : job === 'titles' ? 'Suggest titles with AI'\n : variant === 'explain' && phase !== 'choose' ? 'Explain with AI' : 'Rewrite with AI');\n titleEl.textContent = headTitle();\n // The full title on hover: a long one is cut short with an ellipsis.\n if (variant === 'custom' && instruction && phase !== 'choose') {titleEl.title = instruction;} else {titleEl.title = titleEl.textContent;}\n chooseEl.hidden = phase !== 'choose';\n menuEl.hidden = !!picker;\n formEl.hidden = !!picker;\n pickerEl.hidden = !picker;\n bodyEl.hidden = phase === 'choose' || phase === 'error' || (mode === 'choose' && phase === 'done');\n titlesBoxEl.hidden = !(mode === 'choose' && phase === 'done');\n kindEl.hidden = job !== 'summary';\n for (const seg of kindEl.querySelectorAll<HTMLElement>('.ai-rw-kind-seg')) {\n seg.setAttribute('aria-pressed', seg.dataset.kind === summaryJob?.kind ? 'true' : 'false');\n }\n errorEl.hidden = phase !== 'error';\n footEl.hidden = phase === 'choose' || phase === 'error';\n newLabelEl.textContent = mode === 'readOnly' ? 'Explanation' : variant === 'translate' ? 'Translation' : 'Rewrite';\n renderBadge();\n renderOut();\n\n const ready = phase === 'done' && !!finalText.trim();\n acceptBtn.hidden = phase === 'error' || mode === 'choose';\n acceptBtn.setAttribute('aria-disabled', ready ? 'false' : 'true');\n acceptBtn.textContent = mode === 'readOnly' ? 'Insert below'\n : mode === 'insert' ? 'Insert'\n : mode === 'replaceDocument' ? 'Replace document' : 'Accept';\n acceptBtn.title = mode === 'readOnly'\n ? 'Insert the explanation as a quote below the selection'\n : mode === 'insert' ? 'Insert at the cursor (Enter)'\n : mode === 'replaceDocument' ? 'Replace the document body; frontmatter is kept (Enter)' : 'Replace the selection (Enter)';\n copyBtn.hidden = phase === 'error' || mode === 'choose';\n copyBtn.setAttribute('aria-disabled', (phase === 'done' ? finalText : rewriteVisibleText(raw)).trim() ? 'false' : 'true');\n retryBtn.hidden = phase === 'error';\n noteEl.textContent = repairing ? REPAIR_NOTE : note;\n statsEl.hidden = !(phase === 'done' && stats);\n if (phase === 'done' && stats) {\n statsEl.textContent = aiResultStatsText(stats);\n statsEl.title = aiResultStatsTitle(stats);\n }\n\n // What part of the document was sent, when not all of it fit.\n const covered = job === 'rewrite' ? (target.scope === 'document' ? 'translate' : null) : job;\n const covText = covered && (phase === 'running' || phase === 'done') ? coverageNoteText(covered, coverage) : '';\n coverageEl.hidden = !covText;\n coverageEl.textContent = covText;\n // Esc closes; the button names it (there is no visible hint).\n const closeLabel = mode === 'readOnly' ? 'Close (Esc)' : 'Cancel (Esc)';\n closeBtn.setAttribute('aria-label', closeLabel);\n closeBtn.title = closeLabel;\n\n // The structure check, between the preview and the footer. A warning\n // only: Accept stays enabled.\n warnEl.hidden = !(phase === 'done' && warning);\n if (phase === 'done' && warning) {\n const glyph = el('span', 'ai-rw-warn-icon');\n glyph.innerHTML = WARN;\n warnEl.replaceChildren(glyph, el('span', 'ai-rw-warn-text', warning.text));\n warnEl.title = warning.title;\n }\n\n if (phase === 'error' && error) {renderError(error);}\n }\n\n /** The failing engine's name, when the error says which engine it was and the host can name it. */\n function errorEngine(e: AiError): string | null {\n return e.engineId ? deps.engineName?.(e.engineId) ?? null : null;\n }\n\n /** The copy an error shows: an override, the router's \"No engine can rewrite\", or the code's (naming the engine). */\n function copyFor(e: AiError): AiErrorCopy {\n if (unavailable) {return { title: 'No engine can rewrite right now', message: e.message, action: 'openSettings' as const };}\n const engine = errorEngine(e);\n // The model the request went to, for \"LM Studio couldn't load <model>\".\n const model = route && (!e.engineId || route.engineId === e.engineId) ? route.modelId : undefined;\n return errorCopy ?? aiErrorCopy(e.code, { ...(engine ? { engine } : {}), ...(model ? { model } : {}) });\n }\n\n function renderError(e: AiError): void {\n const copyText = copyFor(e);\n const iconEl = el('span', 'ai-rw-error-icon');\n iconEl.innerHTML = ALERT;\n const textBox = el('div', 'ai-rw-error-text');\n textBox.append(el('div', 'ai-rw-error-title', copyText.title));\n // The router's reason or the host's detail, when it says more than the generic copy.\n const detail = e.message && e.message !== copyText.message ? e.message : '';\n textBox.append(el('div', 'ai-rw-error-message', e.code === 'unknown' && detail ? detail : copyText.message));\n if (detail && e.code === 'modelLoadFailed') {\n // The server's own words are long and technical: one click away.\n const more = el('details', 'ai-rw-error-more');\n more.append(el('summary', undefined, 'Details'), el('div', 'ai-rw-error-detail', detail));\n textBox.append(more);\n } else if (detail && e.code !== 'unknown') {\n textBox.append(el('div', 'ai-rw-error-detail', detail));\n }\n if (e.code === 'contextOverflow' && target) {\n const what = target.scope === 'selection' ? 'The selection' : 'The document';\n const size = job === 'summary' ? summaryJob?.markdown.length ?? 0\n : job === 'titles' ? titleJob?.markdown.length ?? 0 : target.text.length;\n textBox.append(el('div', 'ai-rw-error-detail', `${what} is ${size.toLocaleString()} characters.`));\n }\n const actions = el('div', 'ai-rw-error-actions');\n // An engine problem opens that engine's page, by name (F9).\n const onEngine = (copyText.action === 'openEngine' || copyText.action === 'chooseModel') && !!e.engineId;\n const settingsLabel = copyText.action === 'chooseModel' ? 'Choose model' : onEngine ? `Open ${errorEngine(e) ?? 'engine'}` : 'Open AI settings';\n const primary = copyText.action === 'openSettings' || copyText.action === 'chooseModel' || onEngine;\n const settingsBtn = button(`ai-rw-btn${primary ? ' ai-rw-btn--primary' : ''}`, settingsLabel, () => {\n close({ refocus: false });\n if (onEngine) {deps.openSettings(e.engineId);} else {deps.openSettings();}\n });\n actions.append(settingsBtn);\n if (!unavailable && copyText.action !== 'shortenSelection' && e.code !== 'cloudBlocked') {\n actions.append(button(`ai-rw-btn${copyText.action === 'retry' ? ' ai-rw-btn--primary' : ''}`, e.code === 'badOutput' ? 'Try again' : 'Retry', () => rerun()));\n }\n actions.append(button('ai-rw-btn', 'Close', () => close()));\n errorEl.replaceChildren(iconEl, textBox, actions);\n }\n\n function position(): void {\n if (!root || !target) {return;}\n if (!target.alive()) { close({ refocus: false }); return; }\n const rect = target.rect();\n // Not measurable right now (scrolled out of a virtualised view): stay put.\n if (!rect) {return;}\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const gap = 8;\n const w = root.offsetWidth || 440;\n const h = root.offsetHeight || 200;\n // Pick a side once, with room for the tallest state, so streaming never flips it.\n if (!side) {\n const reserve = Math.min(vh * 0.55, 380);\n side = rect.bottom + gap + reserve <= vh - gap || rect.top - gap - reserve < gap ? 'below' : 'above';\n }\n let top = side === 'below' ? rect.bottom + gap : rect.top - gap - h;\n top = Math.max(gap, Math.min(top, vh - h - gap));\n const left = Math.max(gap, Math.min(rect.left, vw - w - gap));\n root.style.top = `${Math.round(top)}px`;\n root.style.left = `${Math.round(left)}px`;\n }\n\n /** Arrow keys, Home and End move between the chips of the first level, the picker's rows or the titles. */\n function moveFocus(e: KeyboardEvent): boolean {\n const inTitles = outputMode() === 'choose' && phase === 'done';\n if (!root || (phase !== 'choose' && !inTitles) || !/^(Arrow(Up|Down|Left|Right)|Home|End)$/.test(e.key)) {return false;}\n const selector = inTitles ? '.ai-rw-titles > button' : picker ? '.ai-rw-picker-list > button' : '.ai-rw-menu .ai-rw-chip';\n const items = [...root.querySelectorAll<HTMLButtonElement>(selector)];\n const i = items.indexOf(e.target as HTMLButtonElement);\n if (i < 0) {return false;}\n const forward = e.key === 'ArrowDown' || e.key === 'ArrowRight';\n const next = e.key === 'Home' ? 0\n : e.key === 'End' ? items.length - 1\n : (i + (forward ? 1 : -1) + items.length) % items.length;\n items[next].focus({ preventScroll: true });\n return true;\n }\n\n function mount(t: AiRewriteTarget): void {\n close({ refocus: false });\n target = t;\n side = null;\n raw = '';\n finalText = '';\n summaryCutOff = false;\n route = null;\n served = null;\n stats = null;\n viaFallback = false;\n thinking = null;\n error = null;\n unavailable = false;\n note = '';\n warning = null;\n picker = null;\n params = {};\n variant = 'shorter';\n instruction = '';\n docOnly = t.scope === 'document';\n wholeDocument = docOnly;\n job = 'rewrite';\n summaryJob = null;\n titleJob = null;\n titles = [];\n coverage = 1;\n sentText = '';\n untranslated = '';\n repairing = false;\n root = build();\n getPortal().appendChild(root);\n\n const onKey = (e: KeyboardEvent): void => {\n if (!root) {return;}\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n // Esc in a picker goes back to the first level.\n if (phase === 'choose' && picker) {closePicker();} else {close();}\n return;\n }\n if (root.contains(e.target as Node) && moveFocus(e)) {\n e.preventDefault();\n return;\n }\n // Enter accepts a replacement or inserts a summary; Explain inserts\n // only on an explicit click, and a title is picked on its own row.\n const mode = outputMode();\n if (e.key === 'Enter' && phase === 'done' && mode !== 'readOnly' && mode !== 'choose' && !e.shiftKey && !e.altKey) {\n const t2 = e.target as HTMLElement | null;\n const inField = !!t2 && (t2.tagName === 'INPUT' || t2.tagName === 'TEXTAREA');\n const onOtherButton = !!t2 && t2.tagName === 'BUTTON' && t2 !== acceptBtn && root.contains(t2);\n if ((!inField && !onOtherButton) || e.metaKey || e.ctrlKey) {\n e.preventDefault();\n e.stopPropagation();\n accept();\n }\n }\n };\n const onDown = (e: MouseEvent): void => {\n if (root && !root.contains(e.target as Node)) {close({ refocus: false });}\n };\n const onMove = (): void => position();\n document.addEventListener('keydown', onKey, true);\n document.addEventListener('mousedown', onDown, true);\n window.addEventListener('resize', onMove);\n document.addEventListener('scroll', onMove, true);\n detach.push(\n () => document.removeEventListener('keydown', onKey, true),\n () => document.removeEventListener('mousedown', onDown, true),\n () => window.removeEventListener('resize', onMove),\n () => document.removeEventListener('scroll', onMove, true),\n );\n }\n\n /** A dial change (null: Default): remembered for every later request (the AI menu's Thinking row too), then the same run again (like Retry). */\n function pickThinking(level: AiThinkingLevel | null): void {\n if (!thinking || phase === 'choose') {return;}\n if ((level ?? THINKING_DEFAULT) === thinkingSelected(thinking)) {return;}\n rememberThinkingLevel(level);\n // Checked at once; the route's answer confirms it.\n thinking = { ...thinking, sent: level, auto: false };\n const label = level ? thinkingChoices(thinking.kind).find((c) => c.level === level)?.label ?? level : 'Default';\n rerun();\n liveEl.textContent = `Thinking: ${label}`;\n }\n\n /** Run the current job again (Retry, Try again, the thinking dial). */\n function rerun(): void {\n if (job === 'summary') {startSummary();}\n else if (job === 'titles') {startTitles();}\n else {start(variant, instruction);}\n }\n\n /** The routed model's context window for `feature` (unknown: `DEFAULT_CONTEXT_TOKENS`). */\n function contextTokensFor(feature: string): number {\n return deps.routeInfo?.(feature).contextTokens ?? DEFAULT_CONTEXT_TOKENS;\n }\n\n /** Abort what runs and reset for a new request; returns its sequence number and signal. */\n function beginRun(): { seq: number; signal: AbortSignal } {\n abort();\n const ac = new AbortController();\n controller = ac;\n phase = 'running';\n raw = '';\n finalText = '';\n summaryCutOff = false;\n served = null;\n stats = null;\n error = null;\n errorCopy = null;\n note = '';\n warning = null;\n repairing = false;\n return { seq: runSeq, signal: ac.signal };\n }\n\n function runEvents(seq: number): AiRunEvents {\n return {\n onRoute: (r, th) => {\n if (seq !== runSeq) {return;}\n route = r;\n thinking = th;\n raw = '';\n renderBadge();\n renderOut();\n },\n onToken: (_delta, text) => {\n if (seq !== runSeq) {return;}\n raw = text;\n scheduleOut();\n },\n };\n }\n\n /** The feature and scope of the current job, for the privacy copy (consent, badge and chip tooltips). */\n function jobSends(): { feature: string; sends: AiSendsScope } {\n if (job === 'summary') {return { feature: 'summary', sends: 'document' };}\n if (job === 'titles') {return { feature: 'title', sends: 'document' };}\n return { feature: 'rewrite', sends: target?.scope === 'document' ? 'document' : 'selection' };\n }\n\n function noteServed(outcome: AiRunOutcome): void {\n // The feature rides along so the sidebar chip can say what the last request sent.\n const by: AiServedRequest = { ...outcome.result.served, ...jobSends() };\n served = by;\n stats = aiResultStats(outcome.result);\n viaFallback = outcome.viaFallback;\n thinking = outcome.thinking;\n deps.onServed(by, outcome.viaFallback);\n }\n\n function finishNote(outcome: AiRunOutcome): string {\n const reason = outcome.result.finishReason;\n if (reason === 'length') {return aiLengthLimitCopy({ thinking: aiRunThinkingOn(outcome.thinking), empty: false }).message;}\n return reason === 'error' ? 'The stream ended early.' : '';\n }\n\n /** An answer with no text that stopped at the length limit: the error says why. */\n function showLengthError(outcome: AiRunOutcome): void {\n const copy = aiLengthLimitCopy({ thinking: aiRunThinkingOn(outcome.thinking), empty: true });\n errorCopy = copy;\n showError(makeAiError('badOutput', copy.message));\n }\n\n function showError(e: AiError): void {\n phase = 'error';\n error = e;\n repairing = false;\n render();\n position();\n liveEl.textContent = `${copyFor(e).title}.`;\n errorEl.querySelector<HTMLButtonElement>('.ai-rw-btn--primary, .ai-rw-btn')?.focus({ preventScroll: true });\n }\n\n function runFailed(seq: number): (err: unknown) => void {\n return (err) => {\n if (seq !== runSeq || !root) {return;}\n controller = null;\n const e = toAiError(err);\n if (e.code === 'cancelled') {return;}\n showError(e);\n };\n }\n\n // ── Document jobs ──────────────────────────────────────────────────────\n\n function pickKind(kind: AiSummaryKind): void {\n if (!summaryJob || summaryJob.kind === kind) {return;}\n summaryJob.kind = kind;\n startSummary();\n }\n\n /** `/summary`, `/outline`: budget the body, stream the summary, Insert when done. Never retried (D16). */\n function startSummary(): void {\n const t = target;\n const sj = summaryJob;\n if (!t || !root || !sj) {return;}\n const { seq, signal } = beginRun();\n const kind = sj.kind;\n const b = budgetDocument(sj.markdown, {\n contextTokens: contextTokensFor('summary'),\n outputTokens: summaryMaxTokens(kind, sj.markdown.length),\n reserveTokens: DOCUMENT_RESERVE_TOKENS,\n });\n coverage = b.coverage;\n render();\n position();\n root.focus({ preventScroll: true });\n deps.run({\n feature: 'summary',\n messages: buildSummaryMessages({ document: b.text, kind, coverage: b.coverage }),\n maxTokens: summaryMaxTokens(kind, b.text.length),\n temperature: 0.3,\n thinking: thinkingLevelFor,\n job: 'summary',\n }, runEvents(seq), signal).then((outcome) => {\n if (seq !== runSeq || !root) {return;}\n controller = null;\n noteServed(outcome);\n raw = outcome.result.text || raw;\n const cutOff = outcome.result.finishReason === 'length';\n summaryCutOff = cutOff;\n finalText = finalizeSummary(raw, kind, coverage, cutOff);\n if (!finalText.trim()) {\n if (cutOff) {showLengthError(outcome);} else {showError(makeAiError('badOutput'));}\n return;\n }\n phase = 'done';\n note = finishNote(outcome);\n render();\n position();\n liveEl.textContent = `${kind === 'outline' ? 'Outline' : 'Summary'} ready. Press Enter to insert or Escape to cancel.`;\n acceptBtn.focus({ preventScroll: true });\n }, runFailed(seq));\n }\n\n /** `/title`: budget the body (plus every heading), ask for three titles, one JSON repair round trip. */\n function startTitles(): void {\n const t = target;\n const tj = titleJob;\n if (!t || !root || !tj) {return;}\n const { seq, signal } = beginRun();\n titles = [];\n const info = deps.routeInfo?.('title');\n const outline = headingsOutline(tj.markdown);\n const b = budgetDocument(tj.markdown, {\n contextTokens: info?.contextTokens ?? DEFAULT_CONTEXT_TOKENS,\n outputTokens: titleMaxTokens(3),\n reserveTokens: DOCUMENT_RESERVE_TOKENS + Math.ceil(renderHeadingOutline(outline).length / CHARS_PER_TOKEN),\n });\n coverage = b.coverage;\n render();\n position();\n root.focus({ preventScroll: true });\n const messages = buildTitleMessages({ document: b.text, outline, existingTitle: tj.existingTitle, count: 3 });\n const request = (msgs: AiMessage[]): Promise<AiRunOutcome> => deps.run({\n feature: 'title',\n messages: msgs,\n maxTokens: titleMaxTokens(3),\n temperature: 0.7,\n thinking: thinkingLevelFor,\n job: 'title',\n ...(info?.json ? { format: 'json' as const } : {}),\n }, runEvents(seq), signal);\n request(messages).then(async (first) => {\n if (seq !== runSeq || !root) {return;}\n noteServed(first);\n const firstText = first.result.text || raw;\n // Nothing to repair: the model ran out of room before it answered.\n if (!rewriteVisibleText(firstText).trim() && first.result.finishReason === 'length') {\n controller = null;\n showLengthError(first);\n return;\n }\n let last = first;\n let parsed = parseTitles(firstText, tj.existingTitle);\n if (!parsed.ok) {\n // D16: one repair round trip, abortable like the first request.\n repairing = true;\n render();\n const second = await request([...messages, ...jsonRepairMessages(firstText, parsed.error)]);\n if (seq !== runSeq || !root) {return;}\n noteServed(second);\n repairing = false;\n last = second;\n parsed = parseTitles(second.result.text || raw, tj.existingTitle);\n if (!parsed.ok) {\n if (second.result.finishReason === 'length') {\n controller = null;\n showLengthError(second);\n return;\n }\n throw makeAiError('badOutput', parsed.error);\n }\n }\n controller = null;\n titles = parsed.titles.slice(0, 3);\n phase = 'done';\n note = finishNote(last);\n renderTitles();\n render();\n position();\n liveEl.textContent = `${titles.length} ${titles.length === 1 ? 'title' : 'titles'} ready. ${AI_TITLE_EFFECT_HINTS[tj.effect]}. Escape cancels.`;\n titlesEl.querySelector<HTMLButtonElement>('button')?.focus({ preventScroll: true });\n }).catch(runFailed(seq));\n }\n\n function renderTitles(): void {\n titlesEl.replaceChildren(...titles.map((title) => {\n const b = button('ai-rw-option ai-rw-title-option', '', () => pickTitle(title));\n b.setAttribute('role', 'menuitem');\n b.append(el('span', 'ai-rw-option-label', title));\n return b;\n }));\n titleHintEl.textContent = titleJob ? AI_TITLE_EFFECT_HINTS[titleJob.effect] : '';\n }\n\n function pickTitle(title: string): void {\n const t = target;\n const tj = titleJob;\n if (!t || !tj || phase !== 'done') {return;}\n const ok = tj.apply(title);\n close({ refocus: true });\n if (!ok) {t.focus();}\n }\n\n function start(v: AiRewriteVariant, custom?: string): void {\n const t = target;\n if (!t || !root) {return;}\n const { seq, signal } = beginRun();\n variant = v;\n instruction = v === 'custom' ? (custom ?? instruction) : '';\n picker = null;\n oldTextEl.textContent = t.scope === 'document' ? '' : t.text.trim();\n const def = getAiRewriteVariant(v);\n if (def?.param === 'language' && params.language) {rememberLanguage(params.language);}\n if (def?.param === 'audience' && params.audience) {rememberAudience(params.audience);}\n const readOnly = def?.output === 'readOnly';\n\n // A whole document is fitted to the routed model's context: the part\n // that fits is translated, the rest is kept as it is (coverage note).\n sentText = t.text;\n untranslated = '';\n coverage = 1;\n let maxTokens = readOnly ? explainMaxTokens() : rewriteMaxTokens(t.text, v);\n if (t.scope === 'document' && !readOnly) {\n const b = budgetTranslation(t.text, contextTokensFor('rewrite'));\n sentText = b.text;\n untranslated = b.rest;\n coverage = b.coverage;\n maxTokens = b.maxTokens;\n }\n render();\n position();\n root.focus({ preventScroll: true });\n\n const messages = readOnly\n ? buildExplainMessages({ selection: t.text, before: t.before, after: t.after, title: t.title })\n : buildRewriteMessages({\n variant: v,\n instruction,\n selection: sentText,\n before: t.before,\n after: t.after,\n params: def?.param ? params : undefined,\n scope: t.scope === 'document' ? 'document' : 'selection',\n });\n deps.run({\n feature: 'rewrite',\n ...(t.scope === 'document' ? { sends: 'document' as const } : {}),\n messages,\n maxTokens,\n temperature: v === 'fixFlow' || v === 'translate' ? 0.2 : 0.5,\n thinking: thinkingLevelFor,\n // Explain keeps the model's own thinking; every other variant is a short edit (Off).\n job: readOnly ? 'explain' : v === 'translate' ? 'translate' : 'rewrite',\n }, runEvents(seq), signal).then((outcome) => {\n if (seq !== runSeq || !root) {return;}\n controller = null;\n noteServed(outcome);\n // Explain is a note, not a version of the selection: no whitespace to carry over.\n finalText = finalizeRewriteText(outcome.result.text || raw, readOnly ? '' : sentText);\n if (!finalText.trim()) {\n phase = 'error';\n if (outcome.result.finishReason === 'length') {\n errorCopy = aiLengthLimitCopy({ thinking: aiRunThinkingOn(outcome.thinking), empty: true });\n error = makeAiError('badOutput', errorCopy.message);\n } else {\n error = { code: 'unknown', message: 'The engine sent back no text.' };\n }\n } else {\n phase = 'done';\n note = finishNote(outcome);\n if (STRUCTURE_CHECKED.has(v)) {\n const diff = checkMarkdownStructure(sentText, finalText);\n const text = structureWarningText(diff);\n warning = text ? { text, title: diff.messages.join('\\n') } : null;\n }\n }\n render();\n position();\n liveEl.textContent = phase !== 'done' ? 'Rewrite failed.'\n : readOnly ? 'Explanation ready. Insert below adds it to the document; Escape closes.'\n : `${variant === 'translate' ? 'Translation' : 'Rewrite'} ready. Press Enter to accept or Escape to cancel.${warning ? ` ${warning.text}.` : ''}`;\n if (phase === 'done') {\n // Explain leaves the keyboard on the popover so Enter cannot insert by accident.\n (readOnly ? root : acceptBtn).focus({ preventScroll: true });\n }\n }, runFailed(seq));\n }\n\n function accept(): void {\n const t = target;\n const mode = outputMode();\n if (!t || phase !== 'done' || !finalText.trim() || mode === 'choose') {return;}\n const ok = mode === 'readOnly' ? t.insertBelow(finalText)\n // A translation cut to fit keeps the untranslated rest after it.\n : mode === 'replaceDocument' && untranslated.trim() ? t.accept(`${finalText.trimEnd()}\\n\\n${untranslated.trimStart()}`)\n : t.accept(finalText);\n close({ refocus: true });\n if (!ok) {t.focus();}\n }\n\n function copy(): void {\n const text = (phase === 'done' ? finalText : rewriteVisibleText(raw)).trim();\n if (!text) {return;}\n void navigator.clipboard?.writeText(text).then(() => {\n if (!root) {return;}\n copyBtn.textContent = 'Copied';\n window.clearTimeout(copiedTimer);\n copiedTimer = window.setTimeout(() => { copyBtn.textContent = 'Copy'; }, 1200);\n }, () => { /* clipboard refused */ });\n }\n\n return {\n open(t, choice) {\n mount(t);\n params = { ...choice?.params };\n wholeDocument = docOnly || !!choice?.wholeDocument;\n const def = choice ? getAiRewriteVariant(choice.variant) : undefined;\n // The document itself (nothing selected) can only be translated.\n if (docOnly && (!def || def.id !== 'translate' || !hasParam(def, params))) {\n openPicker('language');\n return;\n }\n if (def && def.param && !hasParam(def, params)) {\n openPicker(def.param === 'language' ? 'language' : 'audience');\n return;\n }\n if (def && (def.id !== 'custom' || choice?.instruction?.trim())) {\n if (def.id === 'translate' && wholeDocument && !useDocumentTarget()) {\n wholeDocument = false;\n openPicker('language');\n return;\n }\n start(def.id, choice?.instruction);\n return;\n }\n phase = 'choose';\n render();\n position();\n inputEl.focus({ preventScroll: true });\n },\n openSummary(t, sj) {\n mount(t);\n job = 'summary';\n summaryJob = { ...sj };\n startSummary();\n },\n openTitles(t, tj) {\n mount(t);\n job = 'titles';\n titleJob = tj;\n startTitles();\n },\n openUnavailable(t, reason) {\n mount(t);\n phase = 'error';\n error = { code: 'unknown', message: reason };\n unavailable = true;\n render();\n position();\n errorEl.querySelector<HTMLButtonElement>('.ai-rw-btn')?.focus({ preventScroll: true });\n },\n close: () => close(),\n isOpen: () => !!target,\n destroy() {\n close({ refocus: false });\n },\n };\n}\n","/**\n * A small, safe markdown renderer for the AI result popover's preview.\n *\n * Model output is untrusted text. This builds DOM with `createElement` and\n * `textContent` only: no `innerHTML`, no raw HTML passthrough (a `<script>`\n * stays literal text) and no `href` or `src` is ever set, so a link shows\n * its label and nothing can be followed or fetched from the preview.\n *\n * Covers what models return for summaries, outlines and rewrites:\n * paragraphs, ATX headings, nested bullet and numbered lists, block quotes,\n * fenced code, rules, and inline code, bold, italic, strikethrough, links\n * and images (as their label). Anything else stays literal. Newlines inside\n * a paragraph are kept (the preview is `white-space: pre-wrap`), so plain\n * prose looks as it did when the preview was raw text.\n */\n\nconst FENCE = /^ {0,3}(`{3,}|~{3,})/;\nconst HEADING = /^ {0,3}(#{1,6})[ \\t]+(.*?)(?:[ \\t]+#+)?[ \\t]*$/;\nconst ITEM = /^([ \\t]*)([-*+]|\\d{1,9}[.)])[ \\t]+(.*)$/;\nconst QUOTE = /^ {0,3}>[ \\t]?(.*)$/;\nconst RULE = /^ {0,3}([-*_])(?:[ \\t]*\\1){2,}[ \\t]*$/;\n\nconst isSpace = (c: string | undefined): boolean => c === undefined || /\\s/.test(c);\nconst isWord = (c: string | undefined): boolean => c !== undefined && /[\\p{L}\\p{N}]/u.test(c);\n\nfunction make<K extends keyof HTMLElementTagNameMap>(tag: K, className?: string): HTMLElementTagNameMap[K] {\n const node = document.createElement(tag);\n if (className) {node.className = className;}\n return node;\n}\n\n/** Index of the closer for a delimiter opened at `from`, or -1. */\nfunction findCloser(s: string, delim: string, from: number): number {\n for (let j = s.indexOf(delim, from); j !== -1; j = s.indexOf(delim, j + 1)) {\n if (s[j - 1] === '\\\\' || isSpace(s[j - 1])) {continue;}\n // A single `*` or `_` is not the first half of a doubled one.\n if (delim.length === 1 && (s[j + 1] === delim || s[j - 1] === delim)) {continue;}\n if (delim === '_' && isWord(s[j + 1])) {continue;}\n return j;\n }\n return -1;\n}\n\n/** Index just past the `)` of a `](url)` that starts at `close`, or -1. */\nfunction linkEnd(s: string, close: number): number {\n if (s[close + 1] !== '(') {return -1;}\n let depth = 0;\n for (let k = close + 1; k < s.length; k++) {\n if (s[k] === '\\n') {return -1;}\n if (s[k] === '(') {depth++;} else if (s[k] === ')' && --depth === 0) {return k + 1;}\n }\n return -1;\n}\n\nfunction matchingBracket(s: string, open: number): number {\n let depth = 0;\n for (let k = open; k < s.length; k++) {\n if (s[k] === '\\\\') {k++;} else if (s[k] === '[') {depth++;} else if (s[k] === ']' && --depth === 0) {return k;}\n }\n return -1;\n}\n\n/** Append `s` to `parent` with its inline markdown as elements. */\nfunction appendInline(parent: Node, s: string): void {\n let buf = '';\n const flush = (): void => {\n if (buf) {parent.appendChild(document.createTextNode(buf)); buf = '';}\n };\n const wrap = (tag: 'strong' | 'em' | 'del' | 'span', inner: string, className?: string): void => {\n flush();\n const node = make(tag, className);\n appendInline(node, inner);\n parent.appendChild(node);\n };\n let i = 0;\n while (i < s.length) {\n const c = s[i];\n if (c === '\\\\' && i + 1 < s.length && /[\\\\`*_{}[\\]()#+\\-.!~>|]/.test(s[i + 1])) {\n buf += s[i + 1];\n i += 2;\n continue;\n }\n if (c === '`') {\n let n = 1;\n while (s[i + n] === '`') {n++;}\n const run = '`'.repeat(n);\n const end = s.indexOf(run, i + n);\n if (end !== -1 && s[end + n] !== '`') {\n flush();\n const code = make('code');\n code.textContent = s.slice(i + n, end).replace(/^ (.*) $/, '$1');\n parent.appendChild(code);\n i = end + n;\n continue;\n }\n buf += run;\n i += n;\n continue;\n }\n if (c === '*' || c === '_') {\n const doubled = s[i + 1] === c;\n const delim = doubled ? c + c : c;\n const after = s[i + delim.length];\n const leftOk = c === '*' || !isWord(s[i - 1]);\n if (leftOk && !isSpace(after) && after !== c) {\n const end = findCloser(s, delim, i + delim.length);\n if (end > i + delim.length) {\n wrap(doubled ? 'strong' : 'em', s.slice(i + delim.length, end));\n i = end + delim.length;\n continue;\n }\n }\n buf += delim;\n i += delim.length;\n continue;\n }\n if (c === '~' && s[i + 1] === '~' && !isSpace(s[i + 2])) {\n const end = findCloser(s, '~~', i + 2);\n if (end > i + 2) {\n wrap('del', s.slice(i + 2, end));\n i = end + 2;\n continue;\n }\n }\n if (c === '[' || (c === '!' && s[i + 1] === '[')) {\n const open = c === '!' ? i + 1 : i;\n const close = matchingBracket(s, open);\n const end = close === -1 ? -1 : linkEnd(s, close);\n if (end !== -1) {\n // The label only: the target is never put on the element.\n wrap('span', s.slice(open + 1, close), c === '!' ? 'ai-rw-md-image' : 'ai-rw-md-link');\n i = end;\n continue;\n }\n }\n buf += c;\n i++;\n }\n flush();\n}\n\ninterface ListFrame {\n indent: number;\n ordered: boolean;\n list: HTMLElement;\n item: HTMLElement | null;\n}\n\nconst indentOf = (ws: string): number => ws.replace(/\\t/g, ' ').length;\n\n/** Replace the children of `into` with `markdown`, rendered. */\nexport function renderPreviewMarkdown(into: HTMLElement, markdown: string): void {\n const out: Node[] = [];\n const lines = markdown.replace(/\\r\\n?/g, '\\n').split('\\n');\n let i = 0;\n\n const startsBlock = (line: string): boolean => FENCE.test(line) || HEADING.test(line) || ITEM.test(line) || QUOTE.test(line) || RULE.test(line);\n\n while (i < lines.length) {\n const line = lines[i];\n if (!line.trim()) {i++; continue;}\n\n const fence = FENCE.exec(line);\n if (fence) {\n const marker = fence[1];\n const body: string[] = [];\n i++;\n // An unclosed fence (a stream still running) shows what it has.\n while (i < lines.length && !new RegExp(`^ {0,3}${marker[0]}{${marker.length},}[ \\\\t]*$`).test(lines[i])) {body.push(lines[i++]);}\n i++;\n const pre = make('pre', 'ai-rw-md-pre');\n const code = make('code');\n code.textContent = body.join('\\n');\n pre.appendChild(code);\n out.push(pre);\n continue;\n }\n\n const heading = HEADING.exec(line);\n if (heading) {\n const node = make('div', 'ai-rw-md-h');\n node.dataset.level = String(heading[1].length);\n appendInline(node, heading[2]);\n out.push(node);\n i++;\n continue;\n }\n\n if (RULE.test(line)) {\n out.push(make('hr', 'ai-rw-md-hr'));\n i++;\n continue;\n }\n\n if (QUOTE.test(line)) {\n const inner: string[] = [];\n while (i < lines.length && QUOTE.test(lines[i])) {inner.push(QUOTE.exec(lines[i++])![1]);}\n const quote = make('blockquote', 'ai-rw-md-quote');\n renderPreviewMarkdown(quote, inner.join('\\n'));\n out.push(quote);\n continue;\n }\n\n if (ITEM.test(line)) {\n const stack: ListFrame[] = [];\n const roots: HTMLElement[] = [];\n while (i < lines.length) {\n const m = ITEM.exec(lines[i]);\n if (!m) {\n // A blank line ends the list unless an item follows it; an indented line continues the item.\n if (lines[i].trim() && /^[ \\t]+\\S/.test(lines[i]) && !startsBlock(lines[i]) && stack.length) {\n const item = stack[stack.length - 1].item!;\n item.appendChild(document.createTextNode(`\\n${lines[i].trim()}`));\n i++;\n continue;\n }\n if (!lines[i].trim() && ITEM.test(lines[i + 1] ?? '')) {i++; continue;}\n break;\n }\n const indent = indentOf(m[1]);\n const ordered = /\\d/.test(m[2]);\n while (stack.length && indent < stack[stack.length - 1].indent) {stack.pop();}\n let top = stack[stack.length - 1];\n if (top && indent === top.indent && ordered !== top.ordered) {stack.pop(); top = stack[stack.length - 1];}\n if (!top || indent > top.indent) {\n const list = make(ordered ? 'ol' : 'ul', 'ai-rw-md-list');\n if (ordered) {\n const start = parseInt(m[2], 10);\n if (start !== 1) {list.setAttribute('start', String(start));}\n }\n if (top?.item) {top.item.appendChild(list);} else {roots.push(list);}\n top = { indent, ordered, list, item: null };\n stack.push(top);\n }\n const li = make('li');\n appendInline(li, m[3]);\n top.list.appendChild(li);\n top.item = li;\n i++;\n }\n out.push(...roots);\n continue;\n }\n\n const para: string[] = [];\n while (i < lines.length && lines[i].trim() && (para.length === 0 || !startsBlock(lines[i]))) {para.push(lines[i++]);}\n const p = make('p', 'ai-rw-md-p');\n appendInline(p, para.join('\\n'));\n out.push(p);\n }\n into.replaceChildren(...out);\n}\n"],"mappings":"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","names":["icon","el","from","to","$to","button","THINKING_DEFAULT","note","el","button","position","copy"]}
|