@spotpatch/runtime 1.13.0 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/controller/contextual-ask-workflow.ts","../src/api/contextual-ask-api.ts","../src/api/contextual-ask-response-validation.ts","../src/ui/contextual-ask-localization.ts","../src/ui/contextual-ask-panel.ts","../src/contextual-ask-panel-entry.ts"],"sourcesContent":["import {\n CONTEXTUAL_ASK_SCHEMA_VERSION,\n type AskAnswerResult,\n type AskDraftOrigin,\n type AskJobEvent,\n type AskJobSnapshot,\n type SpotAskTaskEnvelope,\n} from \"@spotpatch/shared/contextual-ask-browser\";\n\nimport {\n contextualAskApiErrorCode,\n createContextualAskApi,\n} from \"../api/contextual-ask-api.js\";\nimport type {\n ContextualAskExtension,\n ContextualAskWorkflow,\n} from \"../ui/contextual-ask-contract.js\";\n\ntype WorkflowInput = Parameters<ContextualAskExtension[\"createWorkflow\"]>[0];\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n\nexport function createContextualAskWorkflow(\n input: WorkflowInput,\n): ContextualAskWorkflow {\n let mounted = false;\n let revision = 0;\n let busy = false;\n let currentSnapshot: AskJobSnapshot | undefined;\n let currentResult: AskAnswerResult | undefined;\n let currentQuestion = \"\";\n let capabilityLoaded = false;\n let composing = false;\n const consentByExecutor = new Map<string, boolean>();\n const api =\n input.api ??\n createContextualAskApi({\n fetch: input.fetch,\n sessionToken: input.sessionToken,\n });\n\n function isCurrent(requestRevision: number): boolean {\n return mounted && revision === requestRevision;\n }\n\n function createEnvelope(question: string): SpotAskTaskEnvelope | undefined {\n const selection = input.getSelection();\n if (question.length === 0 || question.length > 4_000 || selection === undefined) {\n return undefined;\n }\n const createdAt = new Date().toISOString();\n return {\n schemaVersion: CONTEXTUAL_ASK_SCHEMA_VERSION,\n taskId: input.createId(),\n selection: {\n schemaVersion: CONTEXTUAL_ASK_SCHEMA_VERSION,\n selectionId: input.createId(),\n locale: selection.locale,\n targets: selection.targets.map((snapshot) => ({\n targetId: snapshot.id,\n page: snapshot.page,\n source: snapshot.source,\n react: {\n ...snapshot.react,\n componentStack: [...snapshot.react.componentStack],\n },\n element: snapshot.element,\n styles: {\n ...snapshot.styles,\n classNames: [...snapshot.styles.classNames],\n matchedRules: snapshot.styles.matchedRules.map((rule) => ({ ...rule })),\n computed: { ...snapshot.styles.computed },\n warnings: [...snapshot.styles.warnings],\n },\n ...(snapshot.code === undefined ? {} : { code: snapshot.code }),\n warnings: [],\n })),\n createdAt,\n },\n task: { kind: \"ask\", question },\n createdAt,\n };\n }\n\n async function loadCapability(): Promise<void> {\n if (capabilityLoaded) return;\n const requestRevision = revision;\n input.panel.renderCapability(undefined);\n try {\n const capability = await api.capability();\n if (!isCurrent(requestRevision)) return;\n capabilityLoaded = true;\n input.panel.renderCapability(capability);\n const executorId = input.panel.readExecutorId();\n input.panel.setConsent(\n executorId !== undefined && consentByExecutor.get(executorId) === true,\n );\n } catch (error: unknown) {\n if (!isCurrent(requestRevision) || isAbortError(error)) return;\n input.panel.renderError(contextualAskApiErrorCode(error));\n }\n }\n\n function handleEvent(event: AskJobEvent, requestRevision: number): void {\n if (!isCurrent(requestRevision)) return;\n input.panel.renderEvent(event);\n if (event.type === \"snapshot\") currentSnapshot = event.snapshot;\n }\n\n async function submit(): Promise<void> {\n if (busy) return;\n const question = input.panel.readQuestion();\n const executorId = input.panel.readExecutorId();\n const envelope = createEnvelope(question);\n if (\n question.length === 0 ||\n executorId === undefined ||\n !input.panel.readConsent() ||\n envelope === undefined\n ) {\n return;\n }\n\n const requestRevision = ++revision;\n currentQuestion = question;\n busy = true;\n input.onBusyChange(true);\n currentResult = undefined;\n currentSnapshot = undefined;\n input.panel.setBusy(true);\n try {\n const snapshot = await api.createJob({\n schemaVersion: CONTEXTUAL_ASK_SCHEMA_VERSION,\n requestId: input.createId(),\n envelope,\n executorId,\n providerDataConsent: true,\n });\n if (!isCurrent(requestRevision)) return;\n currentSnapshot = snapshot;\n input.panel.renderJob(snapshot);\n await api.events(snapshot.jobId, 0, (event) => {\n handleEvent(event, requestRevision);\n });\n if (!isCurrent(requestRevision)) return;\n const response = await api.result(snapshot.jobId);\n if (!isCurrent(requestRevision)) return;\n currentSnapshot = response.snapshot;\n busy = false;\n input.onBusyChange(false);\n if (response.result === undefined) {\n input.panel.renderJob(response.snapshot);\n if (response.snapshot.status === \"failed\") {\n input.panel.renderError(response.snapshot.errorCode);\n }\n return;\n }\n currentResult = response.result;\n input.panel.renderAnswer(response.result, false);\n } catch (error: unknown) {\n if (!isCurrent(requestRevision) || isAbortError(error)) return;\n busy = false;\n input.onBusyChange(false);\n input.panel.renderError(contextualAskApiErrorCode(error));\n } finally {\n if (isCurrent(requestRevision)) {\n busy = false;\n input.panel.setBusy(false);\n }\n }\n }\n\n async function cancel(): Promise<void> {\n if (!busy || currentSnapshot?.canCancel !== true) return;\n const requestRevision = revision;\n try {\n const snapshot = await api.cancelJob(currentSnapshot.jobId);\n if (!isCurrent(requestRevision)) return;\n currentSnapshot = snapshot;\n busy = false;\n input.onBusyChange(false);\n input.panel.renderJob(snapshot);\n input.panel.setBusy(false);\n } catch (error: unknown) {\n if (!isCurrent(requestRevision) || isAbortError(error)) return;\n busy = false;\n input.onBusyChange(false);\n input.panel.renderError(contextualAskApiErrorCode(error));\n }\n }\n\n function cancelPending(): void {\n revision += 1;\n const snapshot = currentSnapshot;\n busy = false;\n input.onBusyChange(false);\n currentSnapshot = undefined;\n api.cancelPending();\n if (snapshot?.canCancel === true) {\n void api.cancelJob(snapshot.jobId).catch(() => undefined);\n }\n input.panel.setBusy(false);\n }\n\n function newQuestion(): void {\n if (busy) cancelPending();\n revision += 1;\n currentSnapshot = undefined;\n currentResult = undefined;\n currentQuestion = \"\";\n input.panel.clear();\n input.panel.focusQuestion();\n }\n\n function copyAnswer(): void {\n const text = input.panel.answerPlainText();\n if (text.length === 0 || input.clipboard === undefined) return;\n void input.clipboard\n .writeText(text)\n .then(() => {\n input.panel.notify(\"copied\");\n })\n .catch(() => {\n input.panel.notify(\"copy-failed\");\n });\n }\n\n function convert(): void {\n if (currentResult === undefined || busy) return;\n const answerDigest = input.panel.answerPlainText().trim().slice(0, 4_000);\n if (answerDigest.length === 0) return;\n const origin: AskDraftOrigin = Object.freeze({\n kind: \"contextual-ask\",\n askJobId: currentResult.jobId,\n question: currentQuestion,\n answerDigest,\n sourceIds: currentResult.sources.map((source) => source.sourceId),\n });\n input.onConvert(origin);\n input.panel.setOrigin(origin);\n input.panel.setMode(\"change\");\n input.panel.notify(\"converted\");\n }\n\n function openSource(event: MouseEvent): void {\n const sourceId = input.panel.selectedSourceId(event.target);\n if (sourceId === undefined) return;\n const source = input.panel.sourceById(sourceId);\n if (source !== undefined) {\n void input.onOpenSource(source).catch(() => {\n input.panel.notify(\"source-open-failed\");\n });\n }\n }\n\n function keydown(event: KeyboardEvent): void {\n if (\n event.target !== input.panel.questionInput ||\n event.key !== \"Enter\" ||\n composing ||\n event.isComposing ||\n (!event.metaKey && !event.ctrlKey)\n ) {\n return;\n }\n event.preventDefault();\n void submit();\n }\n\n function executorChanged(): void {\n const executorId = input.panel.readExecutorId();\n input.panel.setConsent(\n executorId !== undefined && consentByExecutor.get(executorId) === true,\n );\n }\n\n function compositionStart(): void {\n composing = true;\n }\n\n function compositionEnd(): void {\n composing = false;\n }\n\n function consentChanged(): void {\n const executorId = input.panel.readExecutorId();\n if (executorId !== undefined) {\n consentByExecutor.set(executorId, input.panel.readConsent());\n }\n }\n\n function submitClick(): void {\n void submit();\n }\n\n function cancelClick(): void {\n void cancel();\n }\n\n function mount(): void {\n if (mounted) return;\n mounted = true;\n input.panel.submitButton.addEventListener(\"click\", submitClick);\n input.panel.cancelButton.addEventListener(\"click\", cancelClick);\n input.panel.newQuestionButton.addEventListener(\"click\", newQuestion);\n input.panel.copyButton.addEventListener(\"click\", copyAnswer);\n input.panel.convertButton.addEventListener(\"click\", convert);\n input.panel.executorSelect.addEventListener(\"change\", executorChanged);\n input.panel.consentCheckbox.addEventListener(\"change\", consentChanged);\n input.panel.questionInput.addEventListener(\"keydown\", keydown);\n input.panel.questionInput.addEventListener(\"compositionstart\", compositionStart);\n input.panel.questionInput.addEventListener(\"compositionend\", compositionEnd);\n input.panel.root.addEventListener(\"click\", openSource);\n void loadCapability();\n }\n\n function dispose(): void {\n if (!mounted) return;\n cancelPending();\n mounted = false;\n input.panel.submitButton.removeEventListener(\"click\", submitClick);\n input.panel.cancelButton.removeEventListener(\"click\", cancelClick);\n input.panel.newQuestionButton.removeEventListener(\"click\", newQuestion);\n input.panel.copyButton.removeEventListener(\"click\", copyAnswer);\n input.panel.convertButton.removeEventListener(\"click\", convert);\n input.panel.executorSelect.removeEventListener(\"change\", executorChanged);\n input.panel.consentCheckbox.removeEventListener(\"change\", consentChanged);\n input.panel.questionInput.removeEventListener(\"keydown\", keydown);\n input.panel.questionInput.removeEventListener(\"compositionstart\", compositionStart);\n input.panel.questionInput.removeEventListener(\"compositionend\", compositionEnd);\n input.panel.root.removeEventListener(\"click\", openSource);\n api.dispose();\n }\n\n return Object.freeze({\n beginSelection(): void {\n revision += 1;\n busy = false;\n input.onBusyChange(false);\n currentSnapshot = undefined;\n currentResult = undefined;\n currentQuestion = \"\";\n input.panel.clear();\n void loadCapability();\n },\n cancelPending,\n dispose,\n isBusy: () => busy,\n mount,\n selectionChanged(): void {\n if (currentResult !== undefined) input.panel.renderAnswer(currentResult, true);\n },\n });\n}\n","import {\n SPOTPATCH_ENDPOINTS,\n SPOTPATCH_TOKEN_HEADER,\n getAskJobEndpoint,\n isErrorCode,\n type AskJobCreateRequest,\n type AskJobEvent,\n type AskJobResultResponse,\n type AskJobSnapshot,\n type ContextualAskCapability,\n type ErrorCode,\n} from \"@spotpatch/shared/contextual-ask-browser\";\n\nimport {\n isAskJobEvent,\n isAskJobResultResponse,\n isAskJobSnapshot,\n isContextualAskCapability,\n} from \"./contextual-ask-response-validation.js\";\n\nconst MAX_JSON_RESPONSE_BYTES = 2_000_000;\nconst MAX_EVENT_LINE_BYTES = 100_000;\nconst MAX_EVENT_STREAM_BYTES = 4_000_000;\n\nexport class ContextualAskApiError extends Error {\n constructor(readonly code?: ErrorCode) {\n super(\"SpotPatch Contextual Ask request failed.\");\n this.name = \"ContextualAskApiError\";\n }\n}\n\nexport interface ContextualAskApi {\n readonly capability: () => Promise<ContextualAskCapability>;\n readonly cancelJob: (jobId: string) => Promise<AskJobSnapshot>;\n readonly cancelPending: () => void;\n readonly createJob: (request: AskJobCreateRequest) => Promise<AskJobSnapshot>;\n readonly dispose: () => void;\n readonly events: (\n jobId: string,\n afterSequence: number,\n onEvent: (event: AskJobEvent) => void,\n ) => Promise<void>;\n readonly result: (jobId: string) => Promise<AskJobResultResponse>;\n}\n\ninterface ContextualAskApiOptions {\n readonly fetch: typeof globalThis.fetch;\n readonly sessionToken: string;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction deepFreezeUnknown(value: unknown): void {\n if ((!isRecord(value) && !Array.isArray(value)) || Object.isFrozen(value)) return;\n for (const nested of Object.values(value)) deepFreezeUnknown(nested);\n Object.freeze(value);\n}\n\nfunction deepFreeze<T>(value: T): T {\n deepFreezeUnknown(value);\n return value;\n}\n\nfunction parseJson(text: string): unknown {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n throw new ContextualAskApiError();\n }\n}\n\nasync function readBoundedText(\n response: Response,\n maximumBytes: number,\n): Promise<string> {\n const declaredLength = Number(response.headers.get(\"content-length\"));\n if (Number.isFinite(declaredLength) && declaredLength > maximumBytes) {\n await response.body?.cancel();\n throw new ContextualAskApiError();\n }\n if (response.body === null) throw new ContextualAskApiError();\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n let bytes = 0;\n let output = \"\";\n try {\n for (;;) {\n const chunk = await reader.read();\n if (chunk.done) return output + decoder.decode();\n bytes += chunk.value.byteLength;\n if (bytes > maximumBytes) {\n await reader.cancel();\n throw new ContextualAskApiError();\n }\n output += decoder.decode(chunk.value, { stream: true });\n }\n } catch (error: unknown) {\n if (\n error instanceof ContextualAskApiError ||\n (error instanceof DOMException && error.name === \"AbortError\")\n ) {\n throw error;\n }\n throw new ContextualAskApiError();\n } finally {\n reader.releaseLock();\n }\n}\n\nasync function readEnvelope(response: Response): Promise<unknown> {\n const payload = parseJson(await readBoundedText(response, MAX_JSON_RESPONSE_BYTES));\n if (!isRecord(payload)) throw new ContextualAskApiError();\n if (!response.ok) {\n const code =\n payload.ok === false && isRecord(payload.error) && isErrorCode(payload.error.code)\n ? payload.error.code\n : undefined;\n throw new ContextualAskApiError(code);\n }\n if (payload.ok !== true || !(\"data\" in payload)) throw new ContextualAskApiError();\n return payload.data;\n}\n\nexport function contextualAskApiErrorCode(error: unknown): ErrorCode | undefined {\n return error instanceof ContextualAskApiError ? error.code : undefined;\n}\n\nexport function createContextualAskApi(\n options: ContextualAskApiOptions,\n): ContextualAskApi {\n const pending = new Set<AbortController>();\n\n function cancelPending(): void {\n for (const controller of pending) controller.abort();\n pending.clear();\n }\n\n async function request(\n endpoint: string,\n method: \"GET\" | \"POST\",\n body?: unknown,\n ): Promise<unknown> {\n const controller = new AbortController();\n pending.add(controller);\n try {\n const response = await options.fetch(endpoint, {\n method,\n headers: {\n ...(body === undefined ? {} : { \"Content-Type\": \"application/json\" }),\n [SPOTPATCH_TOKEN_HEADER]: options.sessionToken,\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n signal: controller.signal,\n });\n return await readEnvelope(response);\n } finally {\n pending.delete(controller);\n }\n }\n\n async function events(\n jobId: string,\n afterSequence: number,\n onEvent: (event: AskJobEvent) => void,\n ): Promise<void> {\n const controller = new AbortController();\n pending.add(controller);\n try {\n const response = await options.fetch(\n getAskJobEndpoint(jobId, \"events\", { afterSequence }),\n {\n method: \"GET\",\n headers: { [SPOTPATCH_TOKEN_HEADER]: options.sessionToken },\n signal: controller.signal,\n },\n );\n if (!response.ok) {\n await readEnvelope(response);\n return;\n }\n if (response.body === null) throw new ContextualAskApiError();\n const reader = response.body.getReader();\n const decoder = new TextDecoder(\"utf-8\", { fatal: true });\n let buffer = \"\";\n let totalBytes = 0;\n let previousSequence = afterSequence;\n const consumeLine = (line: string): void => {\n if (line.trim().length === 0) return;\n if (new TextEncoder().encode(line).byteLength > MAX_EVENT_LINE_BYTES) {\n throw new ContextualAskApiError();\n }\n const event = parseJson(line);\n if (\n !isAskJobEvent(event) ||\n event.jobId !== jobId ||\n event.sequence <= previousSequence\n ) {\n throw new ContextualAskApiError();\n }\n previousSequence = event.sequence;\n onEvent(deepFreeze(event));\n };\n try {\n for (;;) {\n const chunk = await reader.read();\n if (chunk.done) {\n consumeLine(buffer + decoder.decode());\n return;\n }\n totalBytes += chunk.value.byteLength;\n if (totalBytes > MAX_EVENT_STREAM_BYTES) {\n await reader.cancel();\n throw new ContextualAskApiError();\n }\n buffer += decoder.decode(chunk.value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n if (new TextEncoder().encode(buffer).byteLength > MAX_EVENT_LINE_BYTES) {\n await reader.cancel();\n throw new ContextualAskApiError();\n }\n for (const line of lines) consumeLine(line);\n }\n } catch (error: unknown) {\n if (\n error instanceof ContextualAskApiError ||\n (error instanceof DOMException && error.name === \"AbortError\")\n ) {\n throw error;\n }\n throw new ContextualAskApiError();\n } finally {\n reader.releaseLock();\n }\n } finally {\n pending.delete(controller);\n }\n }\n\n return Object.freeze({\n async capability(): Promise<ContextualAskCapability> {\n const data = await request(SPOTPATCH_ENDPOINTS.askCapability, \"GET\");\n if (!isContextualAskCapability(data)) throw new ContextualAskApiError();\n return deepFreeze(data);\n },\n async cancelJob(jobId: string): Promise<AskJobSnapshot> {\n const data = await request(getAskJobEndpoint(jobId, \"cancel\"), \"POST\", {});\n if (!isAskJobSnapshot(data) || data.jobId !== jobId) {\n throw new ContextualAskApiError();\n }\n return deepFreeze(data);\n },\n cancelPending,\n async createJob(requestBody: AskJobCreateRequest): Promise<AskJobSnapshot> {\n const data = await request(SPOTPATCH_ENDPOINTS.askJobs, \"POST\", requestBody);\n if (\n !isAskJobSnapshot(data) ||\n data.selectionId !== requestBody.envelope.selection.selectionId ||\n data.executor.executorId !== requestBody.executorId\n ) {\n throw new ContextualAskApiError();\n }\n return deepFreeze(data);\n },\n dispose: cancelPending,\n events,\n async result(jobId: string): Promise<AskJobResultResponse> {\n const data = await request(getAskJobEndpoint(jobId, \"result\"), \"GET\");\n if (!isAskJobResultResponse(data) || data.snapshot.jobId !== jobId) {\n throw new ContextualAskApiError();\n }\n return deepFreeze(data);\n },\n });\n}\n","import {\n ASK_ANSWER_WARNING_CODES,\n ASK_FILE_COUNT_BUCKETS,\n ASK_JOB_STATUSES,\n ASK_READ_ACTIVITY_STATES,\n ASK_SOURCE_CONFIDENCES,\n CONTEXTUAL_ASK_EXECUTOR_KINDS,\n CONTEXTUAL_ASK_EXECUTOR_STATES,\n CONTEXTUAL_ASK_SCHEMA_VERSION,\n isErrorCode,\n type AskAnswerBlock,\n type AskAnswerResult,\n type AskSourceReference,\n type AskJobEvent,\n type AskJobResultResponse,\n type AskJobSnapshot,\n type ContextualAskCapability,\n type ContextualAskExecutorCapability,\n} from \"@spotpatch/shared/contextual-ask-browser\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasOnlyKeys(\n value: UnknownRecord,\n required: readonly string[],\n optional: readonly string[] = [],\n): boolean {\n const keys = Object.keys(value);\n const allowed = new Set([...required, ...optional]);\n return required.every((key) => key in value) && keys.every((key) => allowed.has(key));\n}\n\nfunction isEnum<T extends string>(value: unknown, values: readonly T[]): value is T {\n return typeof value === \"string\" && values.includes(value as T);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n\nfunction isOpaqueId(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n value.length <= 128 &&\n /^[A-Za-z0-9_-]+$/u.test(value)\n );\n}\n\nfunction isTimestamp(value: unknown): value is string {\n return typeof value === \"string\" && Number.isFinite(Date.parse(value));\n}\n\nfunction isPositiveInteger(value: unknown): value is number {\n return Number.isSafeInteger(value) && Number(value) > 0;\n}\n\nfunction isAskDomainError(value: unknown): value is string {\n return isErrorCode(value) && value.startsWith(\"ASK_\");\n}\n\nfunction isStringArray(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((item) => isOpaqueId(item));\n}\n\nfunction unique(values: readonly string[]): boolean {\n return new Set(values).size === values.length;\n}\n\nfunction isExecutorCapability(\n value: unknown,\n): value is ContextualAskExecutorCapability {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(\n value,\n [\n \"executorId\",\n \"kind\",\n \"label\",\n \"requestedModelLabel\",\n \"effectiveModelLabel\",\n \"state\",\n \"providerDataConsentRequired\",\n \"readOnlyProven\",\n ],\n [\"errorCode\"],\n ) ||\n !isOpaqueId(value.executorId) ||\n !isEnum(value.kind, CONTEXTUAL_ASK_EXECUTOR_KINDS) ||\n !isNonEmptyString(value.label) ||\n !isNonEmptyString(value.requestedModelLabel) ||\n !isNonEmptyString(value.effectiveModelLabel) ||\n !isEnum(value.state, CONTEXTUAL_ASK_EXECUTOR_STATES) ||\n typeof value.providerDataConsentRequired !== \"boolean\" ||\n typeof value.readOnlyProven !== \"boolean\" ||\n (value.errorCode !== undefined && !isAskDomainError(value.errorCode))\n ) {\n return false;\n }\n\n return value.state === \"ready\"\n ? value.readOnlyProven && value.errorCode === undefined\n : value.errorCode !== undefined;\n}\n\nexport function isContextualAskCapability(\n value: unknown,\n): value is ContextualAskCapability {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(value, [\n \"schemaVersion\",\n \"enabled\",\n \"executors\",\n \"safety\",\n \"checkedAt\",\n ]) ||\n value.schemaVersion !== CONTEXTUAL_ASK_SCHEMA_VERSION ||\n typeof value.enabled !== \"boolean\" ||\n !Array.isArray(value.executors) ||\n !value.executors.every(isExecutorCapability) ||\n !isRecord(value.safety) ||\n !hasOnlyKeys(value.safety, [\n \"selectionRequired\",\n \"singleTurn\",\n \"writesAllowed\",\n \"historyStored\",\n ]) ||\n value.safety.selectionRequired !== true ||\n value.safety.singleTurn !== true ||\n value.safety.writesAllowed !== false ||\n value.safety.historyStored !== false ||\n !isTimestamp(value.checkedAt)\n ) {\n return false;\n }\n\n const ids = value.executors.map((executor) => executor.executorId);\n return (value.enabled || value.executors.length === 0) && unique(ids);\n}\n\nfunction isExecutorSnapshot(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, [\"executorId\", \"kind\", \"label\", \"modelLabel\"]) &&\n isOpaqueId(value.executorId) &&\n isEnum(value.kind, CONTEXTUAL_ASK_EXECUTOR_KINDS) &&\n isNonEmptyString(value.label) &&\n isNonEmptyString(value.modelLabel)\n );\n}\n\nexport function isAskJobSnapshot(value: unknown): value is AskJobSnapshot {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(\n value,\n [\n \"schemaVersion\",\n \"jobId\",\n \"selectionId\",\n \"status\",\n \"executor\",\n \"createdAt\",\n \"updatedAt\",\n \"canCancel\",\n ],\n [\"phaseMessage\", \"errorCode\"],\n ) ||\n value.schemaVersion !== CONTEXTUAL_ASK_SCHEMA_VERSION ||\n !isOpaqueId(value.jobId) ||\n !isOpaqueId(value.selectionId) ||\n !isEnum(value.status, ASK_JOB_STATUSES) ||\n !isExecutorSnapshot(value.executor) ||\n !isTimestamp(value.createdAt) ||\n !isTimestamp(value.updatedAt) ||\n Date.parse(value.updatedAt) < Date.parse(value.createdAt) ||\n typeof value.canCancel !== \"boolean\" ||\n (value.phaseMessage !== undefined && !isNonEmptyString(value.phaseMessage)) ||\n (value.errorCode !== undefined && !isAskDomainError(value.errorCode))\n ) {\n return false;\n }\n\n const cancellable = [\"queued\", \"authorizing\", \"running\"].includes(value.status);\n if (value.canCancel !== cancellable) return false;\n if (value.status === \"cancelled\") return value.errorCode === \"ASK_CANCELLED\";\n if (value.status === \"failed\") {\n return value.errorCode !== undefined && value.errorCode !== \"ASK_CANCELLED\";\n }\n return value.errorCode === undefined;\n}\n\nfunction isSourceReference(value: unknown): value is AskSourceReference {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(\n value,\n [\n \"sourceId\",\n \"label\",\n \"relativePath\",\n \"fileId\",\n \"startLine\",\n \"endLine\",\n \"confidence\",\n \"targetIds\",\n \"contentHash\",\n ],\n [\"sourceVersion\"],\n ) ||\n !isOpaqueId(value.sourceId) ||\n !isNonEmptyString(value.label) ||\n !isNonEmptyString(value.relativePath) ||\n value.relativePath.startsWith(\"/\") ||\n value.relativePath.includes(\"\\\\\") ||\n value.relativePath\n .split(\"/\")\n .some((part) => part === \"\" || part === \".\" || part === \"..\") ||\n !isOpaqueId(value.fileId) ||\n !isPositiveInteger(value.startLine) ||\n !isPositiveInteger(value.endLine) ||\n value.endLine < value.startLine ||\n !isEnum(value.confidence, ASK_SOURCE_CONFIDENCES) ||\n !isStringArray(value.targetIds) ||\n value.targetIds.length === 0 ||\n !unique(value.targetIds) ||\n (value.sourceVersion !== undefined && !isNonEmptyString(value.sourceVersion)) ||\n typeof value.contentHash !== \"string\" ||\n !/^[a-f0-9]{64}$/u.test(value.contentHash)\n ) {\n return false;\n }\n return true;\n}\n\nfunction isAnswerWarning(value: unknown): value is AskAnswerResult[\"warnings\"][number] {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, [\"code\"]) &&\n isEnum(value.code, ASK_ANSWER_WARNING_CODES)\n );\n}\n\nfunction isAnswerBlock(value: unknown): value is AskAnswerBlock {\n if (!isRecord(value) || typeof value.kind !== \"string\") return false;\n if (value.kind === \"paragraph\") {\n return (\n hasOnlyKeys(value, [\"kind\", \"text\", \"sourceIds\"]) &&\n isNonEmptyString(value.text) &&\n isStringArray(value.sourceIds)\n );\n }\n if (value.kind === \"code\") {\n return (\n hasOnlyKeys(value, [\"kind\", \"code\", \"sourceIds\"], [\"language\"]) &&\n typeof value.code === \"string\" &&\n value.code.length > 0 &&\n isStringArray(value.sourceIds) &&\n (value.language === undefined || isNonEmptyString(value.language))\n );\n }\n if (value.kind !== \"list\" || !hasOnlyKeys(value, [\"kind\", \"items\"])) return false;\n return (\n Array.isArray(value.items) &&\n value.items.length > 0 &&\n value.items.every(\n (item) =>\n isRecord(item) &&\n hasOnlyKeys(item, [\"text\", \"sourceIds\"]) &&\n isNonEmptyString(item.text) &&\n isStringArray(item.sourceIds),\n )\n );\n}\n\nfunction isAnswerResult(value: unknown): value is AskAnswerResult {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(value, [\n \"schemaVersion\",\n \"jobId\",\n \"selectionId\",\n \"contextHash\",\n \"executor\",\n \"blocks\",\n \"sources\",\n \"warnings\",\n \"createdAt\",\n \"expiresAt\",\n ]) ||\n value.schemaVersion !== CONTEXTUAL_ASK_SCHEMA_VERSION ||\n !isOpaqueId(value.jobId) ||\n !isOpaqueId(value.selectionId) ||\n typeof value.contextHash !== \"string\" ||\n !/^[a-f0-9]{64}$/u.test(value.contextHash) ||\n !isExecutorSnapshot(value.executor) ||\n !Array.isArray(value.blocks) ||\n value.blocks.length === 0 ||\n !value.blocks.every(isAnswerBlock) ||\n !Array.isArray(value.sources) ||\n !value.sources.every(isSourceReference) ||\n !Array.isArray(value.warnings) ||\n !value.warnings.every(isAnswerWarning) ||\n !isTimestamp(value.createdAt) ||\n !isTimestamp(value.expiresAt) ||\n Date.parse(value.expiresAt) <= Date.parse(value.createdAt)\n ) {\n return false;\n }\n const sources = value.sources.filter(isSourceReference);\n const blocks = value.blocks.filter(isAnswerBlock);\n const answerWarnings = value.warnings.filter(isAnswerWarning);\n const sourceIds = sources.map((source) => source.sourceId);\n if (!unique(sourceIds)) return false;\n const available = new Set(sourceIds);\n const references = blocks.flatMap((block) =>\n block.kind === \"list\"\n ? block.items.flatMap((item) => item.sourceIds)\n : block.sourceIds,\n );\n return (\n references.every((sourceId) => available.has(sourceId)) &&\n sourceIds.every((sourceId) => references.includes(sourceId)) &&\n (references.length > 0 ||\n answerWarnings.some((warning) => warning.code === \"insufficient-evidence\"))\n );\n}\n\nexport function isAskJobResultResponse(value: unknown): value is AskJobResultResponse {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(value, [\"snapshot\"], [\"result\"]) ||\n !isAskJobSnapshot(value.snapshot) ||\n (value.result !== undefined && !isAnswerResult(value.result))\n ) {\n return false;\n }\n const answered = value.snapshot.status === \"answered\";\n return (\n answered === (value.result !== undefined) &&\n (value.result === undefined ||\n (value.result.jobId === value.snapshot.jobId &&\n value.result.selectionId === value.snapshot.selectionId &&\n value.result.executor.executorId === value.snapshot.executor.executorId))\n );\n}\n\nexport function isAskJobEvent(value: unknown): value is AskJobEvent {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(\n value,\n [\"schemaVersion\", \"sequence\", \"jobId\", \"status\", \"timestamp\", \"type\"],\n [\"snapshot\", \"message\", \"activity\", \"state\", \"errorCode\"],\n ) ||\n value.schemaVersion !== CONTEXTUAL_ASK_SCHEMA_VERSION ||\n !isPositiveInteger(value.sequence) ||\n !isOpaqueId(value.jobId) ||\n !isEnum(value.status, ASK_JOB_STATUSES) ||\n !isTimestamp(value.timestamp)\n ) {\n return false;\n }\n if (value.type === \"snapshot\") {\n return (\n hasOnlyKeys(value, [\n \"schemaVersion\",\n \"sequence\",\n \"jobId\",\n \"status\",\n \"timestamp\",\n \"type\",\n \"snapshot\",\n ]) &&\n isAskJobSnapshot(value.snapshot) &&\n value.snapshot.jobId === value.jobId &&\n value.snapshot.status === value.status\n );\n }\n if (value.type === \"phase\") {\n return (\n hasOnlyKeys(value, [\n \"schemaVersion\",\n \"sequence\",\n \"jobId\",\n \"status\",\n \"timestamp\",\n \"type\",\n \"message\",\n ]) &&\n isNonEmptyString(value.message) &&\n ![\"answered\", \"cancelled\", \"failed\"].includes(value.status)\n );\n }\n if (value.type === \"answer-ready\")\n return (\n hasOnlyKeys(value, [\n \"schemaVersion\",\n \"sequence\",\n \"jobId\",\n \"status\",\n \"timestamp\",\n \"type\",\n ]) && value.status === \"answered\"\n );\n if (value.type === \"error\") {\n return (\n hasOnlyKeys(value, [\n \"schemaVersion\",\n \"sequence\",\n \"jobId\",\n \"status\",\n \"timestamp\",\n \"type\",\n \"errorCode\",\n ]) &&\n isAskDomainError(value.errorCode) &&\n ((value.status === \"cancelled\" && value.errorCode === \"ASK_CANCELLED\") ||\n (value.status === \"failed\" && value.errorCode !== \"ASK_CANCELLED\"))\n );\n }\n if (\n value.type !== \"read-activity\" ||\n !hasOnlyKeys(value, [\n \"schemaVersion\",\n \"sequence\",\n \"jobId\",\n \"status\",\n \"timestamp\",\n \"type\",\n \"activity\",\n \"state\",\n ]) ||\n value.status !== \"running\" ||\n !isRecord(value.activity) ||\n !isEnum(value.state, ASK_READ_ACTIVITY_STATES)\n )\n return false;\n return value.activity.kind === \"source\"\n ? hasOnlyKeys(value.activity, [\"kind\", \"sourceId\", \"relativePath\"]) &&\n isOpaqueId(value.activity.sourceId) &&\n isNonEmptyString(value.activity.relativePath)\n : value.activity.kind === \"file-count\" &&\n hasOnlyKeys(value.activity, [\"kind\", \"bucket\"]) &&\n isEnum(value.activity.bucket, ASK_FILE_COUNT_BUCKETS);\n}\n","import type {\n AskAnswerWarningCode,\n AskJobStatus,\n ErrorCode,\n} from \"@spotpatch/shared/contextual-ask-browser\";\nimport type { SpotPatchLocale } from \"@spotpatch/shared\";\n\nexport interface ContextualAskMessages {\n readonly mode: Readonly<{ ask: string; change: string; label: string }>;\n readonly title: string;\n readonly subtitle: string;\n readonly questionLabel: string;\n readonly questionPlaceholder: string;\n readonly suggestionsLabel: string;\n readonly suggestions: readonly string[];\n readonly executorLabel: string;\n readonly loadingExecutors: string;\n readonly noExecutor: string;\n readonly unavailable: string;\n readonly consent: string;\n readonly dataSummary: (targets: number, sources: number) => string;\n readonly safety: string;\n readonly submit: string;\n readonly cancel: string;\n readonly newQuestion: string;\n readonly copy: string;\n readonly convert: string;\n readonly answerTitle: string;\n readonly sourcesTitle: string;\n readonly stale: string;\n readonly convertedTitle: string;\n readonly convertedBody: string;\n readonly status: Readonly<Record<AskJobStatus, string>>;\n readonly sourceLabel: (path: string, start: number, end: number) => string;\n readonly readSource: (path: string) => string;\n readonly readFiles: (bucket: string) => string;\n readonly copied: string;\n readonly copyFailed: string;\n readonly sourceOpenFailed: string;\n readonly converted: string;\n readonly error: (code?: ErrorCode) => string;\n readonly warning: (code: AskAnswerWarningCode) => string;\n}\n\nconst EN: ContextualAskMessages = Object.freeze({\n mode: Object.freeze({ ask: \"Ask\", change: \"Change\", label: \"Task mode\" }),\n title: \"Ask about this selection\",\n subtitle: \"One question, one sourced answer. SpotPatch will not write code.\",\n questionLabel: \"Question\",\n questionPlaceholder: \"What does this component do?\",\n suggestionsLabel: \"Suggested questions\",\n suggestions: Object.freeze([\n \"What does this component do?\",\n \"Where does its data come from?\",\n \"Why is it implemented this way?\",\n ]),\n executorLabel: \"Read-only executor\",\n loadingExecutors: \"Checking available executors…\",\n noExecutor: \"No verified read-only executor is available.\",\n unavailable: \"unavailable\",\n consent:\n \"Allow the selected source snapshot to be sent to this provider for this answer.\",\n dataSummary: (targets: number, sources: number) =>\n `${String(targets)} selected element${targets === 1 ? \"\" : \"s\"} · ${String(sources)} source-backed`,\n safety: \"Single turn · read-only · no history\",\n submit: \"Ask\",\n cancel: \"Cancel\",\n newQuestion: \"Start over\",\n copy: \"Copy answer\",\n convert: \"Turn into change request\",\n answerTitle: \"Answer\",\n sourcesTitle: \"Sources\",\n stale: \"The selection changed after this answer. Ask again before relying on it.\",\n convertedTitle: \"From contextual answer\",\n convertedBody:\n \"The answer and source references remain local and have not started a change.\",\n status: Object.freeze({\n queued: \"Queued\",\n authorizing: \"Verifying read-only access\",\n running: \"Analyzing selected source\",\n cancelling: \"Cancelling\",\n answered: \"Answer ready\",\n cancelled: \"Cancelled\",\n failed: \"Could not answer\",\n }),\n sourceLabel: (path: string, start: number, end: number) =>\n `${path}:${String(start)}${end === start ? \"\" : `–${String(end)}`}`,\n readSource: (path: string) => `Reading ${path}`,\n readFiles: (bucket: string) => `Reading ${bucket} files`,\n copied: \"Answer copied.\",\n copyFailed: \"The answer could not be copied.\",\n sourceOpenFailed: \"The source could not be opened.\",\n converted: \"Switched to Change with the answer attached as local context.\",\n error: (code?: ErrorCode) => {\n const errors: Partial<Record<ErrorCode, string>> = {\n INVALID_TOKEN: \"The local SpotPatch session expired. Refresh the page.\",\n ORIGIN_NOT_ALLOWED:\n \"The local request failed its same-origin security check. Refresh or restart the dev server.\",\n ASK_DISABLED: \"Contextual Ask is disabled.\",\n ASK_SELECTION_REQUIRED: \"Select at least one element first.\",\n ASK_SELECTION_STALE:\n \"The selected source changed. Refresh the selection and ask again.\",\n ASK_QUESTION_INVALID: \"Enter one valid question.\",\n ASK_EXECUTOR_UNAVAILABLE: \"The selected read-only executor is unavailable.\",\n ASK_TIMEOUT:\n \"The read-only executor took too long to answer. Try the question again.\",\n ASK_CONSENT_REQUIRED: \"Confirm provider data access for this answer.\",\n ASK_BUSY: \"Another workspace task is active. Try again when it finishes.\",\n ASK_CANCELLED: \"The question was cancelled.\",\n ASK_RESULT_EXPIRED: \"This answer has expired. Ask again.\",\n ASK_WRITE_ATTEMPTED: \"The executor attempted a write and was stopped.\",\n ASK_ANSWER_INVALID: \"The executor returned an invalid sourced answer.\",\n ASK_PROTOCOL_INCOMPATIBLE: \"The executor protocol is incompatible.\",\n ASK_LIMIT_EXCEEDED: \"The selected context is too large.\",\n ASK_SOURCE_SCOPE_DENIED: \"A requested source was outside the granted snapshot.\",\n };\n return code === undefined\n ? \"SpotPatch could not complete this question.\"\n : (errors[code] ?? \"SpotPatch could not complete this question.\");\n },\n warning: (code: AskAnswerWarningCode) =>\n code === \"insufficient-evidence\"\n ? \"The selected source did not contain enough evidence for a complete answer.\"\n : \"Some source references were omitted because they could not be verified.\",\n});\n\nconst ZH: ContextualAskMessages = Object.freeze({\n mode: Object.freeze({ ask: \"问答\", change: \"修改\", label: \"任务模式\" }),\n title: \"询问所选元素\",\n subtitle: \"一次提问,一次带源码引用的回答;SpotPatch 不会写入代码。\",\n questionLabel: \"问题\",\n questionPlaceholder: \"这个组件是做什么的?\",\n suggestionsLabel: \"推荐问题\",\n suggestions: Object.freeze([\n \"这个组件是做什么的?\",\n \"它的数据从哪里来?\",\n \"为什么要这样实现?\",\n ]),\n executorLabel: \"只读执行器\",\n loadingExecutors: \"正在检查可用执行器…\",\n noExecutor: \"目前没有通过只读验证的执行器。\",\n unavailable: \"不可用\",\n consent: \"允许本次回答将所选源码快照发送给该提供商。\",\n dataSummary: (targets: number, sources: number) =>\n `${String(targets)} 个已选元素 · ${String(sources)} 个具备源码上下文`,\n safety: \"单轮 · 只读 · 不保存历史\",\n submit: \"提问\",\n cancel: \"取消\",\n newQuestion: \"重新开始\",\n copy: \"复制回答\",\n convert: \"转成修改请求\",\n answerTitle: \"回答\",\n sourcesTitle: \"源码引用\",\n stale: \"回答后选择已发生变化。请重新提问后再采信此回答。\",\n convertedTitle: \"来自上下文问答\",\n convertedBody: \"回答与源码引用仅作为本地上下文保留,尚未发起任何修改。\",\n status: Object.freeze({\n queued: \"已排队\",\n authorizing: \"正在验证只读权限\",\n running: \"正在分析所选源码\",\n cancelling: \"正在取消\",\n answered: \"回答已就绪\",\n cancelled: \"已取消\",\n failed: \"无法回答\",\n }),\n sourceLabel: (path: string, start: number, end: number) =>\n `${path}:${String(start)}${end === start ? \"\" : `–${String(end)}`}`,\n readSource: (path: string) => `正在读取 ${path}`,\n readFiles: (bucket: string) => `正在读取 ${bucket} 个文件`,\n copied: \"回答已复制。\",\n copyFailed: \"无法复制回答。\",\n sourceOpenFailed: \"无法打开源码。\",\n converted: \"已切换到修改模式,并把回答作为本地上下文附带。\",\n error: (code?: ErrorCode) => {\n const errors: Partial<Record<ErrorCode, string>> = {\n INVALID_TOKEN: \"本地 SpotPatch 会话已失效,请刷新页面。\",\n ORIGIN_NOT_ALLOWED: \"本地请求未通过同源安全校验,请刷新页面或重启开发服务。\",\n ASK_DISABLED: \"上下文问答未启用。\",\n ASK_SELECTION_REQUIRED: \"请先选择至少一个元素。\",\n ASK_SELECTION_STALE: \"所选源码已经变化,请刷新选择后重新提问。\",\n ASK_QUESTION_INVALID: \"请输入一个有效的问题。\",\n ASK_EXECUTOR_UNAVAILABLE: \"所选只读执行器当前不可用。\",\n ASK_TIMEOUT: \"只读执行器未能在限定时间内返回回答,请重新提问。\",\n ASK_CONSENT_REQUIRED: \"请确认本次回答的提供商数据访问。\",\n ASK_BUSY: \"工作区正在执行其他任务,请稍后重试。\",\n ASK_CANCELLED: \"本次提问已取消。\",\n ASK_RESULT_EXPIRED: \"回答已过期,请重新提问。\",\n ASK_WRITE_ATTEMPTED: \"执行器尝试写入,已被阻止。\",\n ASK_ANSWER_INVALID: \"执行器返回的带引用回答无效。\",\n ASK_PROTOCOL_INCOMPATIBLE: \"执行器协议不兼容。\",\n ASK_LIMIT_EXCEEDED: \"所选上下文过大。\",\n ASK_SOURCE_SCOPE_DENIED: \"请求的源码超出了授权快照范围。\",\n };\n return code === undefined\n ? \"SpotPatch 未能完成本次提问。\"\n : (errors[code] ?? \"SpotPatch 未能完成本次提问。\");\n },\n warning: (code: AskAnswerWarningCode) =>\n code === \"insufficient-evidence\"\n ? \"所选源码不足以支持完整回答。\"\n : \"部分源码引用因无法验证而被省略。\",\n});\n\nexport function contextualAskMessages(locale: SpotPatchLocale): ContextualAskMessages {\n return locale === \"zh-CN\" ? ZH : EN;\n}\n","import type {\n AskAnswerResult,\n AskDraftOrigin,\n AskJobEvent,\n AskJobSnapshot,\n AskSourceReference,\n ContextualAskCapability,\n ErrorCode,\n} from \"@spotpatch/shared/contextual-ask-browser\";\n\nimport { createButton, createMarkedElement } from \"./dom.js\";\nimport type {\n ContextualAskPanel,\n ContextualAskSelectionPreview,\n} from \"./contextual-ask-contract.js\";\nimport {\n contextualAskMessages,\n type ContextualAskMessages,\n} from \"./contextual-ask-localization.js\";\nimport type { FloatingSurfaceProjection } from \"./motion-extension-contract.js\";\n\ninterface CreateContextualAskPanelInput {\n readonly document: Document;\n readonly locale: Parameters<typeof contextualAskMessages>[0] extends never\n ? never\n : () => Parameters<typeof contextualAskMessages>[0];\n readonly subscribeLocale: (listener: () => void) => () => void;\n readonly changeRoot: HTMLElement;\n readonly changeActions: HTMLElement;\n readonly announce: (message: string) => void;\n readonly onModeChange: (\n mode: \"ask\" | \"change\",\n title: string,\n subtitle: string,\n ) => void;\n readonly onExecutionChange: (projection?: FloatingSurfaceProjection) => void;\n readonly onViewChange: () => void;\n}\n\nfunction createStyles(document: Document): HTMLStyleElement {\n const style = document.createElement(\"style\");\n style.textContent = `\n .spotpatch-ask-mode { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-bottom: 14px; padding: 4px; border: 1px solid var(--spotpatch-border-subtle); border-radius: 10px; background: #0a0a0e; }\n .spotpatch-ask-mode button { min-height: 34px; border: 0; border-radius: 7px; color: var(--spotpatch-text-secondary); background: transparent; cursor: pointer; font-size: 12px; font-weight: 700; }\n .spotpatch-ask-mode button[aria-selected=\"true\"] { color: #f7f7ff; background: linear-gradient(135deg, rgb(139 123 255 / 25%), rgb(82 168 255 / 14%)); box-shadow: inset 0 0 0 1px rgb(139 123 255 / 24%); }\n .spotpatch-ask-panel { display: grid; gap: 14px; }\n .spotpatch-ask-field { display: grid; gap: 7px; }\n .spotpatch-ask-field > label, .spotpatch-ask-label { color: #c9cad2; font-size: 11px; font-weight: 680; }\n .spotpatch-ask-question { box-sizing: border-box; width: 100%; min-height: 92px; resize: vertical; border: 1px solid var(--spotpatch-border); border-radius: 10px; padding: 11px 12px; outline: none; color: var(--spotpatch-text); background: var(--spotpatch-bg-input); line-height: 1.55; }\n .spotpatch-ask-question:focus { border-color: rgb(139 123 255 / 68%); box-shadow: 0 0 0 3px rgb(139 123 255 / 12%); }\n .spotpatch-ask-suggestions { display: flex; flex-wrap: wrap; gap: 6px; }\n .spotpatch-ask-suggestions button { border: 1px solid var(--spotpatch-border-subtle); border-radius: 999px; padding: 5px 9px; color: var(--spotpatch-text-secondary); background: rgb(255 255 255 / 2%); cursor: pointer; font-size: 10.5px; }\n .spotpatch-ask-suggestions button:hover { border-color: rgb(139 123 255 / 42%); color: #fff; }\n .spotpatch-ask-executor-picker { display: grid; gap: 5px; min-width: 0; }\n .spotpatch-ask-executor { box-sizing: border-box; display: flex; width: 100%; min-height: 38px; align-items: center; justify-content: space-between; gap: 10px; border: 1px solid var(--spotpatch-border); border-radius: 9px; padding: 0 11px; overflow: hidden; color: var(--spotpatch-text); background: var(--spotpatch-bg-input); cursor: pointer; font: inherit; outline: none; text-align: left; }\n .spotpatch-ask-executor > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .spotpatch-ask-executor[data-expandable=\"true\"]::after { width: 7px; height: 7px; flex: 0 0 auto; border-right: 1.5px solid #8f96a3; border-bottom: 1.5px solid #8f96a3; content: \"\"; transform: translateY(-2px) rotate(45deg); }\n .spotpatch-ask-executor[aria-expanded=\"true\"]::after { transform: translateY(2px) rotate(225deg); }\n .spotpatch-ask-executor:focus-visible { border-color: rgb(139 123 255 / 68%); box-shadow: 0 0 0 3px rgb(139 123 255 / 12%); }\n .spotpatch-ask-executor:disabled { color: var(--spotpatch-text); background: rgb(255 255 255 / 3%); cursor: default; opacity: 1; }\n .spotpatch-ask-executor[data-empty=\"true\"]:disabled { color: var(--spotpatch-text-muted); }\n .spotpatch-ask-executor-menu { display: grid; gap: 3px; border: 1px solid var(--spotpatch-border); border-radius: 9px; padding: 4px; background: #101116; box-shadow: 0 10px 28px rgb(0 0 0 / 28%); }\n .spotpatch-ask-executor-menu[hidden] { display: none; }\n .spotpatch-ask-executor-option { box-sizing: border-box; min-height: 34px; border: 0; border-radius: 6px; padding: 7px 9px; color: var(--spotpatch-text-secondary); background: transparent; cursor: pointer; font: inherit; text-align: left; }\n .spotpatch-ask-executor-option:hover, .spotpatch-ask-executor-option:focus-visible { color: #fff; background: rgb(139 123 255 / 13%); outline: none; }\n .spotpatch-ask-executor-option[aria-selected=\"true\"] { color: #f4f1ff; background: rgb(139 123 255 / 20%); }\n .spotpatch-ask-executor-native { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; border: 0; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }\n .spotpatch-ask-executor-status { margin: 0; border-left: 2px solid var(--spotpatch-warning); padding-left: 8px; color: #d8b66c; font-size: 10.5px; line-height: 1.45; }\n .spotpatch-ask-safety { display: grid; gap: 8px; border: 1px solid rgb(82 168 255 / 16%); border-radius: 10px; padding: 10px 11px; background: rgb(82 168 255 / 4%); }\n .spotpatch-ask-data { display: flex; justify-content: space-between; gap: 10px; color: #aab3c2; font-size: 10.5px; }\n .spotpatch-ask-data strong { color: #9fe3c4; font-weight: 650; white-space: nowrap; }\n .spotpatch-ask-consent { display: grid; grid-template-columns: 16px 1fr; gap: 8px; align-items: start; color: var(--spotpatch-text-secondary); cursor: pointer; font-size: 10.5px; line-height: 1.45; }\n .spotpatch-ask-consent input { margin: 2px 0 0; accent-color: var(--spotpatch-accent); }\n .spotpatch-ask-actions, .spotpatch-ask-answer-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 7px; }\n .spotpatch-ask-actions button, .spotpatch-ask-answer-actions button { min-height: 34px; border: 1px solid var(--spotpatch-border); border-radius: 8px; padding: 0 12px; color: #d6d6de; background: var(--spotpatch-bg-raised); cursor: pointer; font-size: 11px; font-weight: 680; }\n .spotpatch-ask-actions .spotpatch-primary, .spotpatch-ask-answer-actions .spotpatch-primary { border-color: transparent; color: var(--spotpatch-text-on-accent); background: linear-gradient(135deg, #a99cff, #65b7ff); }\n .spotpatch-ask-actions button:disabled, .spotpatch-ask-answer-actions button:disabled { opacity: .45; cursor: not-allowed; }\n .spotpatch-ask-status { display: grid; gap: 7px; border-left: 2px solid var(--spotpatch-accent); padding: 2px 0 2px 10px; color: #c8c9d2; font-size: 11px; }\n .spotpatch-ask-activity { display: grid; gap: 4px; color: var(--spotpatch-text-muted); font: 500 10px/1.45 ui-monospace, SFMono-Regular, Menlo, monospace; }\n .spotpatch-ask-error, .spotpatch-ask-stale, .spotpatch-ask-warning { border-radius: 8px; padding: 9px 10px; font-size: 10.5px; }\n .spotpatch-ask-error { color: #fecaca; background: rgb(251 113 133 / 9%); }\n .spotpatch-ask-stale, .spotpatch-ask-warning { color: #f9d68a; background: rgb(245 158 11 / 8%); }\n .spotpatch-ask-answer { display: grid; gap: 12px; border: 1px solid var(--spotpatch-border-subtle); border-radius: 11px; padding: 12px; background: var(--spotpatch-bg); box-shadow: 0 12px 30px rgb(0 0 0 / 18%); }\n .spotpatch-ask-answer h3, .spotpatch-ask-sources h4 { margin: 0; color: var(--spotpatch-text); font-size: 13px; }\n .spotpatch-ask-blocks { display: grid; gap: 10px; color: #d9dae2; font-size: 12px; line-height: 1.65; overflow-wrap: anywhere; }\n .spotpatch-ask-blocks p, .spotpatch-ask-blocks ul { margin: 0; }\n .spotpatch-ask-blocks ul { padding-left: 18px; }\n .spotpatch-ask-blocks pre { max-width: 100%; overflow: auto; margin: 0; border: 1px solid var(--spotpatch-border-subtle); border-radius: 9px; padding: 10px; color: #dbeafe; background: #08090d; font: 500 10.5px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; }\n .spotpatch-ask-citations, .spotpatch-ask-source-list { display: flex; flex-wrap: wrap; gap: 5px; }\n .spotpatch-ask-source { max-width: 100%; overflow: hidden; border: 1px solid rgb(82 168 255 / 22%); border-radius: 999px; padding: 4px 8px; color: #b8dcff; background: rgb(82 168 255 / 7%); cursor: pointer; font: 550 9.5px/1.3 ui-monospace, SFMono-Regular, Menlo, monospace; text-overflow: ellipsis; white-space: nowrap; }\n .spotpatch-ask-sources { display: grid; gap: 7px; }\n .spotpatch-ask-origin { margin-bottom: 12px; border: 1px solid rgb(139 123 255 / 22%); border-radius: 10px; padding: 10px 11px; color: var(--spotpatch-text-secondary); background: rgb(139 123 255 / 6%); font-size: 10.5px; }\n .spotpatch-ask-origin strong { display: block; margin-bottom: 2px; color: #d9d4ff; font-size: 11px; }\n @media (max-width: 420px) { .spotpatch-ask-data { display: grid; } .spotpatch-ask-actions, .spotpatch-ask-answer-actions { justify-content: stretch; } .spotpatch-ask-actions button, .spotpatch-ask-answer-actions button { flex: 1 1 auto; } }\n @media (prefers-reduced-motion: reduce) { .spotpatch-ask-panel *, .spotpatch-ask-mode * { scroll-behavior: auto !important; transition: none !important; } }\n `;\n return style;\n}\n\nfunction appendSourceChips(\n document: Document,\n root: HTMLElement,\n sourceIds: readonly string[],\n sources: ReadonlyMap<string, AskSourceReference>,\n messages: ContextualAskMessages,\n): void {\n if (sourceIds.length === 0) return;\n const chips = createMarkedElement(document, \"div\");\n chips.className = \"spotpatch-ask-citations\";\n for (const sourceId of sourceIds) {\n const source = sources.get(sourceId);\n if (source === undefined) continue;\n const chip = createButton(\n document,\n messages.sourceLabel(source.relativePath, source.startLine, source.endLine),\n \"spotpatch-ask-source\",\n );\n chip.dataset.askSourceId = source.sourceId;\n chip.title = source.label;\n chips.append(chip);\n }\n root.append(chips);\n}\n\nexport function createContextualAskPanel(\n input: CreateContextualAskPanelInput,\n): ContextualAskPanel {\n const { document } = input;\n let messages = contextualAskMessages(input.locale());\n let currentMode: \"ask\" | \"change\" = \"change\";\n let currentCapability: ContextualAskCapability | undefined;\n let currentResult: AskAnswerResult | undefined;\n let currentJob: AskJobSnapshot | undefined;\n let reportedMode: \"ask\" | \"change\" | undefined;\n let reportedTitle = \"\";\n let reportedSubtitle = \"\";\n let currentPreview: ContextualAskSelectionPreview = Object.freeze({\n contextReady: false,\n targetCount: 0,\n sourceCount: 0,\n });\n let busy = false;\n\n const root = createMarkedElement(document, \"section\");\n const modeSwitch = createMarkedElement(document, \"div\");\n modeSwitch.className = \"spotpatch-ask-mode\";\n modeSwitch.setAttribute(\"role\", \"tablist\");\n const askTab = createButton(document, \"\");\n const changeTab = createButton(document, \"\");\n askTab.setAttribute(\"role\", \"tab\");\n changeTab.setAttribute(\"role\", \"tab\");\n modeSwitch.append(askTab, changeTab);\n\n const origin = createMarkedElement(document, \"aside\");\n origin.className = \"spotpatch-ask-origin\";\n origin.hidden = true;\n const originTitle = createMarkedElement(document, \"strong\");\n const originBody = createMarkedElement(document, \"span\");\n origin.append(originTitle, originBody);\n\n const askPanel = createMarkedElement(document, \"div\");\n askPanel.className = \"spotpatch-ask-panel\";\n const questionField = createMarkedElement(document, \"div\");\n questionField.className = \"spotpatch-ask-field\";\n const questionLabel = createMarkedElement(document, \"label\");\n const questionId = `spotpatch-ask-question-${Math.random().toString(36).slice(2)}`;\n questionLabel.htmlFor = questionId;\n const questionInput = createMarkedElement(document, \"textarea\");\n questionInput.id = questionId;\n questionInput.className = \"spotpatch-ask-question\";\n questionInput.maxLength = 4_000;\n const suggestions = createMarkedElement(document, \"div\");\n suggestions.className = \"spotpatch-ask-suggestions\";\n suggestions.setAttribute(\"aria-label\", \"\");\n questionField.append(questionLabel, questionInput, suggestions);\n\n const executorField = createMarkedElement(document, \"div\");\n executorField.className = \"spotpatch-ask-field\";\n const executorLabel = createMarkedElement(document, \"label\");\n const executorPicker = createMarkedElement(document, \"div\");\n executorPicker.className = \"spotpatch-ask-executor-picker\";\n const executorTrigger = createButton(document, \"\", \"spotpatch-ask-executor\");\n const executorSelect = createMarkedElement(document, \"select\");\n const executorId = `spotpatch-ask-executor-${Math.random().toString(36).slice(2)}`;\n const executorMenuId = `${executorId}-menu`;\n executorTrigger.id = executorId;\n executorTrigger.setAttribute(\"role\", \"combobox\");\n executorTrigger.setAttribute(\"aria-controls\", executorMenuId);\n executorTrigger.setAttribute(\"aria-expanded\", \"false\");\n const executorText = createMarkedElement(document, \"span\");\n executorTrigger.append(executorText);\n const executorMenu = createMarkedElement(document, \"div\");\n executorMenu.id = executorMenuId;\n executorMenu.className = \"spotpatch-ask-executor-menu\";\n executorMenu.setAttribute(\"role\", \"listbox\");\n executorMenu.hidden = true;\n executorSelect.className = \"spotpatch-ask-executor-native\";\n executorSelect.tabIndex = -1;\n executorSelect.setAttribute(\"aria-hidden\", \"true\");\n executorLabel.htmlFor = executorId;\n const executorStatus = createMarkedElement(document, \"p\");\n executorStatus.className = \"spotpatch-ask-executor-status\";\n executorStatus.setAttribute(\"role\", \"status\");\n executorStatus.hidden = true;\n executorPicker.append(executorTrigger, executorMenu, executorSelect);\n executorField.append(executorLabel, executorPicker, executorStatus);\n\n const safety = createMarkedElement(document, \"div\");\n safety.className = \"spotpatch-ask-safety\";\n const dataSummary = createMarkedElement(document, \"div\");\n dataSummary.className = \"spotpatch-ask-data\";\n const dataText = createMarkedElement(document, \"span\");\n const safetyText = createMarkedElement(document, \"strong\");\n dataSummary.append(dataText, safetyText);\n const consentLabel = createMarkedElement(document, \"label\");\n consentLabel.className = \"spotpatch-ask-consent\";\n const consentCheckbox = createMarkedElement(document, \"input\");\n consentCheckbox.type = \"checkbox\";\n const consentText = createMarkedElement(document, \"span\");\n consentLabel.append(consentCheckbox, consentText);\n safety.append(dataSummary, consentLabel);\n\n const status = createMarkedElement(document, \"div\");\n status.className = \"spotpatch-ask-status\";\n status.setAttribute(\"role\", \"status\");\n status.setAttribute(\"aria-live\", \"polite\");\n status.hidden = true;\n const statusText = createMarkedElement(document, \"strong\");\n const activities = createMarkedElement(document, \"div\");\n activities.className = \"spotpatch-ask-activity\";\n status.append(statusText, activities);\n const error = createMarkedElement(document, \"div\");\n error.className = \"spotpatch-ask-error\";\n error.setAttribute(\"role\", \"alert\");\n error.hidden = true;\n\n const actions = createMarkedElement(document, \"div\");\n actions.className = \"spotpatch-ask-actions\";\n const newQuestionButton = createButton(document, \"\");\n const cancelButton = createButton(document, \"\");\n const submitButton = createButton(document, \"\", \"spotpatch-primary\");\n cancelButton.hidden = true;\n actions.append(newQuestionButton, cancelButton, submitButton);\n\n const answer = createMarkedElement(document, \"article\");\n answer.className = \"spotpatch-ask-answer\";\n answer.hidden = true;\n const stale = createMarkedElement(document, \"div\");\n stale.className = \"spotpatch-ask-stale\";\n stale.hidden = true;\n const answerTitle = createMarkedElement(document, \"h3\");\n const warnings = createMarkedElement(document, \"div\");\n const blocks = createMarkedElement(document, \"div\");\n blocks.className = \"spotpatch-ask-blocks\";\n const sourcesSection = createMarkedElement(document, \"section\");\n sourcesSection.className = \"spotpatch-ask-sources\";\n const sourcesTitle = createMarkedElement(document, \"h4\");\n const sourceList = createMarkedElement(document, \"div\");\n sourceList.className = \"spotpatch-ask-source-list\";\n sourcesSection.append(sourcesTitle, sourceList);\n const answerActions = createMarkedElement(document, \"div\");\n answerActions.className = \"spotpatch-ask-answer-actions\";\n const copyButton = createButton(document, \"\");\n const convertButton = createButton(document, \"\", \"spotpatch-primary\");\n answerActions.append(copyButton, convertButton);\n answer.append(stale, answerTitle, warnings, blocks, sourcesSection, answerActions);\n\n askPanel.append(questionField, executorField, safety, status, error, actions, answer);\n root.append(modeSwitch, origin, askPanel);\n\n function hasReadyExecutor(): boolean {\n const selected = currentCapability?.executors.find(\n (candidate) => candidate.executorId === executorSelect.value,\n );\n return selected?.state === \"ready\" && selected.readOnlyProven;\n }\n\n function hasAnyReadyExecutor(): boolean {\n return (\n currentCapability?.executors.some(\n (candidate) => candidate.state === \"ready\" && candidate.readOnlyProven,\n ) === true\n );\n }\n\n function readyExecutorCount(): number {\n return (\n currentCapability?.executors.filter(\n (candidate) => candidate.state === \"ready\" && candidate.readOnlyProven,\n ).length ?? 0\n );\n }\n\n function closeExecutorMenu(focusTrigger = false): void {\n if (executorMenu.hidden) return;\n executorMenu.hidden = true;\n executorTrigger.setAttribute(\"aria-expanded\", \"false\");\n if (focusTrigger) executorTrigger.focus({ preventScroll: true });\n input.onViewChange();\n }\n\n function openExecutorMenu(focusSelected = false): void {\n if (executorTrigger.disabled || !executorMenu.hidden) return;\n executorMenu.hidden = false;\n executorTrigger.setAttribute(\"aria-expanded\", \"true\");\n if (focusSelected) {\n const selected = executorMenu.querySelector<HTMLElement>(\n '.spotpatch-ask-executor-option[aria-selected=\"true\"]',\n );\n const first = executorMenu.firstElementChild;\n const focusTarget = selected ?? (first instanceof HTMLElement ? first : null);\n focusTarget?.focus({ preventScroll: true });\n }\n input.onViewChange();\n }\n\n function syncExecutorControl(): void {\n const selectedOption = [...executorSelect.options].find(\n (option) => option.value === executorSelect.value,\n );\n executorText.textContent = selectedOption?.textContent ?? messages.noExecutor;\n executorTrigger.dataset.empty = String(executorSelect.value.length === 0);\n for (const option of executorMenu.querySelectorAll<HTMLElement>(\n \".spotpatch-ask-executor-option\",\n )) {\n option.setAttribute(\n \"aria-selected\",\n String(option.dataset.executorId === executorSelect.value),\n );\n }\n }\n\n function refreshSubmitState(): void {\n submitButton.disabled =\n busy ||\n questionInput.value.trim().length === 0 ||\n !hasReadyExecutor() ||\n !consentCheckbox.checked ||\n currentPreview.targetCount === 0;\n if (!currentPreview.contextReady) submitButton.disabled = true;\n questionInput.disabled = busy;\n const readyCount = readyExecutorCount();\n const executorUnavailable =\n busy || currentCapability === undefined || !hasAnyReadyExecutor();\n executorSelect.disabled = executorUnavailable;\n executorTrigger.disabled = executorUnavailable || readyCount < 2;\n executorTrigger.dataset.expandable = String(!executorUnavailable && readyCount > 1);\n if (executorTrigger.disabled) closeExecutorMenu();\n consentCheckbox.disabled = busy || !hasReadyExecutor();\n newQuestionButton.hidden = busy || currentResult === undefined;\n cancelButton.hidden = !busy;\n }\n\n function applyMode(): void {\n const asking = currentMode === \"ask\";\n askTab.setAttribute(\"aria-selected\", String(asking));\n changeTab.setAttribute(\"aria-selected\", String(!asking));\n askPanel.hidden = !asking;\n input.changeRoot.hidden = asking;\n input.changeActions.hidden = asking;\n origin.hidden = asking || origin.dataset.active !== \"true\";\n if (\n reportedMode !== currentMode ||\n reportedTitle !== messages.title ||\n reportedSubtitle !== messages.subtitle\n ) {\n reportedMode = currentMode;\n reportedTitle = messages.title;\n reportedSubtitle = messages.subtitle;\n input.onModeChange(currentMode, messages.title, messages.subtitle);\n }\n input.onViewChange();\n }\n\n function renderSuggestions(): void {\n suggestions.replaceChildren();\n for (const suggestion of messages.suggestions) {\n const button = createButton(document, suggestion);\n button.type = \"button\";\n button.addEventListener(\"click\", () => {\n questionInput.value = suggestion;\n refreshSubmitState();\n questionInput.focus();\n });\n suggestions.append(button);\n }\n }\n\n function applyMessages(): void {\n messages = contextualAskMessages(input.locale());\n modeSwitch.setAttribute(\"aria-label\", messages.mode.label);\n askTab.textContent = messages.mode.ask;\n changeTab.textContent = messages.mode.change;\n questionLabel.textContent = messages.questionLabel;\n questionInput.placeholder = messages.questionPlaceholder;\n suggestions.setAttribute(\"aria-label\", messages.suggestionsLabel);\n executorLabel.textContent = messages.executorLabel;\n consentText.textContent = messages.consent;\n safetyText.textContent = messages.safety;\n submitButton.textContent = messages.submit;\n cancelButton.textContent = messages.cancel;\n newQuestionButton.textContent = messages.newQuestion;\n copyButton.textContent = messages.copy;\n convertButton.textContent = messages.convert;\n answerTitle.textContent = messages.answerTitle;\n sourcesTitle.textContent = messages.sourcesTitle;\n stale.textContent = messages.stale;\n originTitle.textContent = messages.convertedTitle;\n originBody.textContent = messages.convertedBody;\n dataText.textContent = messages.dataSummary(\n currentPreview.targetCount,\n currentPreview.sourceCount,\n );\n renderSuggestions();\n renderCapability(currentCapability);\n if (currentResult !== undefined) renderAnswer(currentResult, !stale.hidden);\n }\n\n function renderCapability(capability?: ContextualAskCapability): void {\n currentCapability = capability;\n const previous = executorSelect.value;\n executorSelect.replaceChildren();\n executorMenu.replaceChildren();\n closeExecutorMenu();\n executorStatus.hidden = true;\n executorStatus.textContent = \"\";\n if (capability === undefined) {\n const option = document.createElement(\"option\");\n option.textContent = messages.loadingExecutors;\n option.value = \"\";\n executorSelect.append(option);\n } else if (!capability.enabled || capability.executors.length === 0) {\n const option = document.createElement(\"option\");\n option.textContent = messages.noExecutor;\n option.value = \"\";\n executorSelect.append(option);\n } else {\n const readyExecutors = capability.executors.filter(\n (executor) => executor.state === \"ready\" && executor.readOnlyProven,\n );\n const unavailableExecutors = capability.executors.filter(\n (executor) => executor.state !== \"ready\" || !executor.readOnlyProven,\n );\n for (const executor of readyExecutors) {\n const option = document.createElement(\"option\");\n option.value = executor.executorId;\n option.textContent = `${executor.label} · ${executor.effectiveModelLabel}`;\n executorSelect.append(option);\n const menuOption = createButton(\n document,\n option.textContent,\n \"spotpatch-ask-executor-option\",\n );\n menuOption.dataset.executorId = executor.executorId;\n menuOption.setAttribute(\"role\", \"option\");\n menuOption.addEventListener(\"click\", () => {\n executorSelect.value = executor.executorId;\n syncExecutorControl();\n closeExecutorMenu(true);\n executorSelect.dispatchEvent(new Event(\"change\", { bubbles: true }));\n });\n executorMenu.append(menuOption);\n }\n if (readyExecutors.length === 0) {\n const option = document.createElement(\"option\");\n option.textContent = messages.noExecutor;\n option.value = \"\";\n executorSelect.append(option);\n }\n executorSelect.value = readyExecutors.some(\n (executor) => executor.executorId === previous,\n )\n ? previous\n : (readyExecutors[0]?.executorId ?? \"\");\n if (unavailableExecutors.length > 0) {\n executorStatus.textContent = unavailableExecutors\n .map((executor) => `${executor.label}: ${messages.error(executor.errorCode)}`)\n .join(\" \");\n executorStatus.hidden = false;\n }\n }\n syncExecutorControl();\n refreshSubmitState();\n }\n\n function renderJob(snapshot: AskJobSnapshot): void {\n currentJob = snapshot;\n status.hidden = false;\n error.hidden = true;\n statusText.textContent = messages.status[snapshot.status];\n if ([\"answered\", \"cancelled\", \"failed\"].includes(snapshot.status)) {\n busy = false;\n input.onExecutionChange();\n } else {\n input.onExecutionChange({\n scene: \"running\",\n tone: \"running\",\n headline: messages.status[snapshot.status],\n expandedHeadline: messages.status[snapshot.status],\n action: messages.safety,\n expandedAction: messages.safety,\n meta: `${snapshot.executor.label} · ${snapshot.executor.modelLabel}`,\n recentActivities: Object.freeze([]),\n startedAt: snapshot.createdAt,\n });\n }\n refreshSubmitState();\n }\n\n function renderEvent(event: AskJobEvent): void {\n if (event.type === \"snapshot\") {\n renderJob(event.snapshot);\n return;\n }\n if (event.type === \"phase\") statusText.textContent = messages.status[event.status];\n if (event.type === \"read-activity\" && event.state === \"started\") {\n const line = createMarkedElement(document, \"span\");\n line.textContent =\n event.activity.kind === \"source\"\n ? messages.readSource(event.activity.relativePath)\n : messages.readFiles(event.activity.bucket);\n activities.append(line);\n while (activities.childElementCount > 5) activities.firstElementChild?.remove();\n if (currentJob !== undefined) {\n const activityLabel = line.textContent;\n input.onExecutionChange({\n scene: \"running\",\n tone: \"running\",\n headline: messages.status.running,\n expandedHeadline: messages.status.running,\n action: activityLabel,\n expandedAction: activityLabel,\n meta: `${currentJob.executor.label} · ${currentJob.executor.modelLabel}`,\n activity: {\n key: `ask:${String(event.sequence)}`,\n kind: \"read\",\n label: activityLabel,\n state: \"active\",\n },\n recentActivities: Object.freeze([]),\n startedAt: currentJob.createdAt,\n });\n }\n }\n }\n\n function renderAnswer(result: AskAnswerResult, isStale: boolean): void {\n currentResult = result;\n currentJob = undefined;\n input.onExecutionChange();\n const sourceMap = new Map(\n result.sources.map((source) => [source.sourceId, source]),\n );\n blocks.replaceChildren();\n warnings.replaceChildren();\n sourceList.replaceChildren();\n stale.hidden = !isStale;\n for (const warning of result.warnings) {\n const warningNode = createMarkedElement(document, \"div\");\n warningNode.className = \"spotpatch-ask-warning\";\n warningNode.textContent = messages.warning(warning.code);\n warnings.append(warningNode);\n }\n for (const block of result.blocks) {\n if (block.kind === \"paragraph\") {\n const paragraph = createMarkedElement(document, \"p\");\n paragraph.textContent = block.text;\n blocks.append(paragraph);\n appendSourceChips(document, blocks, block.sourceIds, sourceMap, messages);\n } else if (block.kind === \"code\") {\n const pre = createMarkedElement(document, \"pre\");\n const code = createMarkedElement(document, \"code\");\n if (block.language !== undefined) code.dataset.language = block.language;\n code.textContent = block.code;\n pre.append(code);\n blocks.append(pre);\n appendSourceChips(document, blocks, block.sourceIds, sourceMap, messages);\n } else {\n const list = createMarkedElement(document, \"ul\");\n for (const item of block.items) {\n const listItem = createMarkedElement(document, \"li\");\n listItem.textContent = item.text;\n appendSourceChips(document, listItem, item.sourceIds, sourceMap, messages);\n list.append(listItem);\n }\n blocks.append(list);\n }\n }\n for (const source of result.sources) {\n const button = createButton(\n document,\n messages.sourceLabel(source.relativePath, source.startLine, source.endLine),\n \"spotpatch-ask-source\",\n );\n button.dataset.askSourceId = source.sourceId;\n button.title = source.label;\n sourceList.append(button);\n }\n sourcesSection.hidden = result.sources.length === 0;\n answer.hidden = false;\n status.hidden = true;\n busy = false;\n refreshSubmitState();\n input.onViewChange();\n }\n\n function answerPlainText(): string {\n if (currentResult === undefined) return \"\";\n const body = currentResult.blocks\n .flatMap((block) =>\n block.kind === \"paragraph\"\n ? [block.text]\n : block.kind === \"code\"\n ? [block.code]\n : block.items.map((item) => `- ${item.text}`),\n )\n .join(\"\\n\\n\");\n const sourceText = currentResult.sources\n .map((source) =>\n messages.sourceLabel(source.relativePath, source.startLine, source.endLine),\n )\n .join(\"\\n\");\n return sourceText.length === 0\n ? body\n : `${body}\\n\\n${messages.sourcesTitle}\\n${sourceText}`;\n }\n\n function clear(): void {\n currentResult = undefined;\n currentJob = undefined;\n input.onExecutionChange();\n questionInput.value = \"\";\n answer.hidden = true;\n status.hidden = true;\n error.hidden = true;\n activities.replaceChildren();\n stale.hidden = true;\n busy = false;\n refreshSubmitState();\n input.onViewChange();\n }\n\n askTab.addEventListener(\"click\", () => {\n currentMode = \"ask\";\n applyMode();\n questionInput.focus({ preventScroll: true });\n });\n changeTab.addEventListener(\"click\", () => {\n currentMode = \"change\";\n applyMode();\n });\n questionInput.addEventListener(\"input\", refreshSubmitState);\n executorSelect.addEventListener(\"change\", refreshSubmitState);\n executorTrigger.addEventListener(\"click\", () => {\n if (executorMenu.hidden) openExecutorMenu();\n else closeExecutorMenu();\n });\n executorTrigger.addEventListener(\"keydown\", (event) => {\n if (event.key !== \"ArrowDown\" && event.key !== \"ArrowUp\") return;\n event.preventDefault();\n openExecutorMenu(true);\n });\n executorMenu.addEventListener(\"keydown\", (event) => {\n const options = [\n ...executorMenu.querySelectorAll<HTMLButtonElement>(\n \".spotpatch-ask-executor-option\",\n ),\n ];\n if (event.key === \"Escape\") {\n event.preventDefault();\n closeExecutorMenu(true);\n return;\n }\n if (![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key)) return;\n event.preventDefault();\n const currentIndex = options.indexOf(document.activeElement as HTMLButtonElement);\n const nextIndex =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? options.length - 1\n : event.key === \"ArrowDown\"\n ? (currentIndex + 1 + options.length) % options.length\n : (currentIndex - 1 + options.length) % options.length;\n options[nextIndex]?.focus({ preventScroll: true });\n });\n executorPicker.addEventListener(\"focusout\", (event) => {\n if (\n !(event.relatedTarget instanceof Node) ||\n !executorPicker.contains(event.relatedTarget)\n ) {\n closeExecutorMenu();\n }\n });\n const closeExecutorMenuOutside = (event: PointerEvent): void => {\n if (!event.composedPath().includes(executorPicker)) closeExecutorMenu();\n };\n document.addEventListener(\"pointerdown\", closeExecutorMenuOutside);\n consentCheckbox.addEventListener(\"change\", refreshSubmitState);\n const unsubscribeLocale = input.subscribeLocale(applyMessages);\n applyMessages();\n applyMode();\n\n return Object.freeze({\n root,\n styles: createStyles(document),\n questionInput,\n executorSelect,\n consentCheckbox,\n submitButton,\n cancelButton,\n newQuestionButton,\n copyButton,\n convertButton,\n clear,\n dispose: () => {\n unsubscribeLocale();\n document.removeEventListener(\"pointerdown\", closeExecutorMenuOutside);\n },\n focusQuestion: () => {\n questionInput.focus({ preventScroll: true });\n },\n mode: () => currentMode,\n notify(event: \"copied\" | \"copy-failed\" | \"converted\" | \"source-open-failed\"): void {\n const message =\n event === \"copied\"\n ? messages.copied\n : event === \"copy-failed\"\n ? messages.copyFailed\n : event === \"converted\"\n ? messages.converted\n : messages.sourceOpenFailed;\n input.announce(message);\n },\n readConsent: () => consentCheckbox.checked,\n readExecutorId: () => executorSelect.value || undefined,\n readQuestion: () => questionInput.value.trim(),\n renderAnswer,\n renderCapability,\n renderError(code?: ErrorCode): void {\n currentJob = undefined;\n input.onExecutionChange();\n error.textContent = messages.error(code);\n error.hidden = false;\n status.hidden = true;\n busy = false;\n refreshSubmitState();\n input.onViewChange();\n },\n renderEvent,\n renderJob,\n selectedSourceId(target: EventTarget | null): string | undefined {\n return target instanceof Element\n ? target.closest<HTMLElement>(\"[data-ask-source-id]\")?.dataset.askSourceId\n : undefined;\n },\n setBusy(nextBusy: boolean): void {\n busy = nextBusy;\n if (nextBusy) {\n status.hidden = false;\n error.hidden = true;\n answer.hidden = true;\n activities.replaceChildren();\n }\n refreshSubmitState();\n },\n setConsent(granted: boolean): void {\n consentCheckbox.checked = granted;\n refreshSubmitState();\n },\n setMode(mode: \"ask\" | \"change\"): void {\n currentMode = mode;\n applyMode();\n },\n setOrigin(nextOrigin?: AskDraftOrigin): void {\n origin.dataset.active = String(nextOrigin !== undefined);\n origin.hidden = currentMode === \"ask\" || nextOrigin === undefined;\n input.onViewChange();\n },\n setSelectionPreview(preview: ContextualAskSelectionPreview): void {\n currentPreview = preview;\n dataText.textContent = messages.dataSummary(\n preview.targetCount,\n preview.sourceCount,\n );\n refreshSubmitState();\n },\n setSelectionVisible(visible: boolean): void {\n root.hidden = !visible;\n if (visible) applyMode();\n },\n sourceById: (sourceId: string) =>\n currentResult?.sources.find((source) => source.sourceId === sourceId),\n answerPlainText,\n });\n}\n","import { createContextualAskWorkflow } from \"./controller/contextual-ask-workflow.js\";\nimport {\n registerContextualAskExtension,\n type ContextualAskExtension,\n} from \"./ui/contextual-ask-contract.js\";\nimport { createContextualAskPanel } from \"./ui/contextual-ask-panel.js\";\n\nconst EXTENSION = Object.freeze({\n createPanel: createContextualAskPanel,\n createWorkflow: createContextualAskWorkflow,\n}) satisfies ContextualAskExtension;\n\nexport function installContextualAskExtension(): void {\n registerContextualAskExtension(EXTENSION);\n}\n\nexport { createContextualAskPanel } from \"./ui/contextual-ask-panel.js\";\nexport { createContextualAskWorkflow } from \"./controller/contextual-ask-workflow.js\";\nexport {\n getContextualAskExtension,\n registerContextualAskExtension,\n type ContextualAskExtension,\n type ContextualAskPanel,\n type ContextualAskWorkflow,\n} from \"./ui/contextual-ask-contract.js\";\n"],"mappings":"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","names":["CONTEXTUAL_ASK_SCHEMA_VERSION","isErrorCode","isRecord","isErrorCode","CONTEXTUAL_ASK_SCHEMA_VERSION"]}
package/dist/index.cjs CHANGED
@@ -424,7 +424,7 @@ function omitBrowserCodeContext(request) {
424
424
  };
425
425
  }
426
426
  function runtimeApiErrorCode(error) {
427
- return error instanceof RuntimeApiError ? error.code : void 0;
427
+ return error instanceof RuntimeApiError && isAgentErrorCode(error.code) ? error.code : void 0;
428
428
  }
429
429
  function createRuntimeApi(options) {
430
430
  const pendingRequests = /* @__PURE__ */ new Set();
@@ -2548,6 +2548,12 @@ function getExternalHandoffExtension() {
2548
2548
  return globalThis[EXTERNAL_HANDOFF_EXTENSION_KEY];
2549
2549
  }
2550
2550
 
2551
+ // src/ui/contextual-ask-contract.ts
2552
+ var CONTEXTUAL_ASK_EXTENSION_KEY = /* @__PURE__ */ Symbol.for("spotpatch.contextual-ask.v1");
2553
+ function getContextualAskExtension() {
2554
+ return globalThis[CONTEXTUAL_ASK_EXTENSION_KEY];
2555
+ }
2556
+
2551
2557
  // src/ui/motion-extension-contract.ts
2552
2558
  var MOTION_EXTENSION_KEY = /* @__PURE__ */ Symbol.for("spotpatch.motion.v1");
2553
2559
  function getFloatingSurfaceMotionExtension() {
@@ -4353,7 +4359,7 @@ function createUnavailableDataFlowPanel(document, changesRoot, diagnosticsRoot)
4353
4359
  resetView: () => void 0
4354
4360
  });
4355
4361
  }
4356
- function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto", dataFlowEnabled = false, externalAgentEnabled = false, framework = "vite", sessionId = "") {
4362
+ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: false }), localePreference = "auto", dataFlowEnabled = false, externalAgentEnabled = false, framework = "vite", sessionId = "", contextualAskEnabled = false) {
4357
4363
  const localizer = createUiLocalizer(document, localePreference);
4358
4364
  const associatedWindow = document.defaultView;
4359
4365
  if (associatedWindow === null) {
@@ -4367,6 +4373,9 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4367
4373
  );
4368
4374
  let messages = localizer.messages();
4369
4375
  let currentStatus = "idle";
4376
+ let contextualAskMode = "change";
4377
+ let contextualAskTitle = "";
4378
+ let contextualAskSubtitle = "";
4370
4379
  let plannerVisible = false;
4371
4380
  let executionSuppressed = false;
4372
4381
  let executionProjection;
@@ -4576,6 +4585,29 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4576
4585
  backButton
4577
4586
  );
4578
4587
  actions.append(editorFeedback, secondaryActions, primaryActions);
4588
+ const contextualAskPanel = contextualAskEnabled ? getContextualAskExtension()?.createPanel({
4589
+ document,
4590
+ locale: localizer.locale,
4591
+ subscribeLocale: localizer.subscribe,
4592
+ changeRoot: dataFlowPanel.root,
4593
+ changeActions: actions,
4594
+ announce,
4595
+ onModeChange(mode, askTitle, askSubtitle) {
4596
+ contextualAskMode = mode;
4597
+ contextualAskTitle = askTitle;
4598
+ contextualAskSubtitle = askSubtitle;
4599
+ if (host.isConnected) renderPanelStatus(currentStatus);
4600
+ },
4601
+ onExecutionChange(projection) {
4602
+ executionProjection = projection;
4603
+ executionSuppressed = false;
4604
+ renderFloatingSurfaceMotion();
4605
+ },
4606
+ onViewChange: requestFloatingSurfaceLayout
4607
+ }) : void 0;
4608
+ if (contextualAskPanel !== void 0) {
4609
+ selectionPanel.prepend(contextualAskPanel.root);
4610
+ }
4579
4611
  shell.append(header, body, actions);
4580
4612
  dialog.append(shell);
4581
4613
  const liveRegion = createMarkedElement(document, "div");
@@ -4586,6 +4618,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
4586
4618
  createStyles(document),
4587
4619
  ...motionExtension === void 0 ? [] : [motionExtension.createStyles(document)],
4588
4620
  dataFlowPanel.styles,
4621
+ ...contextualAskPanel === void 0 ? [] : [contextualAskPanel.styles],
4589
4622
  ...externalHandoffPanel === void 0 ? [] : [externalHandoffPanel.styles]
4590
4623
  ];
4591
4624
  const styleNonce = resolveStyleNonce(document);
@@ -5138,6 +5171,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5138
5171
  previewButton.disabled = !canPreview;
5139
5172
  agentPanel.setContextReady(canPreview);
5140
5173
  externalHandoffPanel?.setContextReady(canPreview);
5174
+ contextualAskPanel?.setSelectionPreview({
5175
+ contextReady: currentTargets.every((target2) => target2.status !== "loading"),
5176
+ targetCount: currentTargets.length,
5177
+ sourceCount: currentTargets.filter((target2) => target2.canOpenEditor).length
5178
+ });
5141
5179
  updateContextOverview(summaryText);
5142
5180
  requestFloatingSurfaceLayout();
5143
5181
  }
@@ -5154,10 +5192,11 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5154
5192
  secondaryActions.hidden = !selected;
5155
5193
  agentPanel.setSelectionVisible(selected);
5156
5194
  externalHandoffPanel?.setSelectionVisible(selected);
5195
+ contextualAskPanel?.setSelectionVisible(selected);
5157
5196
  copyButton.hidden = !previewing;
5158
5197
  backButton.hidden = !previewing;
5159
- title.textContent = previewing ? messages.dialog.previewTitle : messages.dialog.editTitle;
5160
- subtitle.textContent = previewing ? messages.dialog.previewSubtitle : messages.dialog.editSubtitle;
5198
+ title.textContent = previewing ? messages.dialog.previewTitle : contextualAskMode === "ask" && contextualAskTitle.length > 0 ? contextualAskTitle : messages.dialog.editTitle;
5199
+ subtitle.textContent = previewing ? messages.dialog.previewSubtitle : contextualAskMode === "ask" && contextualAskSubtitle.length > 0 ? contextualAskSubtitle : messages.dialog.editSubtitle;
5161
5200
  renderFloatingSurfaceMotion();
5162
5201
  }
5163
5202
  function applyMessages() {
@@ -5292,6 +5331,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5292
5331
  agentRevertButton: agentPanel.revertButton,
5293
5332
  agentResetButton: agentPanel.resetButton,
5294
5333
  ...externalHandoffPanel === void 0 ? {} : { externalHandoffPanel },
5334
+ ...contextualAskPanel === void 0 ? {} : { contextualAskPanel },
5295
5335
  renderStatus(status) {
5296
5336
  const inspecting = status === "inspecting";
5297
5337
  if (status === "idle" || inspecting) {
@@ -5365,6 +5405,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5365
5405
  agentPanel.setSelectionVisible(false);
5366
5406
  externalHandoffPanel?.setContextReady(false);
5367
5407
  externalHandoffPanel?.setSelectionVisible(false);
5408
+ contextualAskPanel?.setSelectionVisible(false);
5368
5409
  agentPanel.setEditingEnabled(true);
5369
5410
  agentPanel.resetJob();
5370
5411
  dataFlowPanel.resetView();
@@ -5505,6 +5546,7 @@ function createRuntimeView(document, shortcut, ai = Object.freeze({ enabled: fal
5505
5546
  unsubscribeLocale();
5506
5547
  dataFlowPanel.dispose();
5507
5548
  externalHandoffPanel?.dispose();
5549
+ contextualAskPanel?.dispose();
5508
5550
  agentPanel.dispose();
5509
5551
  motionController?.dispose();
5510
5552
  executionIslandView.dispose();
@@ -6023,7 +6065,8 @@ function createController(config, dependencies = {}) {
6023
6065
  config.dataFlow.enabled,
6024
6066
  config.externalAgent.enabled,
6025
6067
  config.framework,
6026
- config.sessionId
6068
+ config.sessionId,
6069
+ config.contextualAsk.enabled
6027
6070
  );
6028
6071
  const api = dependencies.api ?? createRuntimeApi({
6029
6072
  apiBase: config.apiBase,
@@ -6226,6 +6269,19 @@ function createController(config, dependencies = {}) {
6226
6269
  (target2) => target2.instruction.trim().length > 0 && target2.elementContext !== void 0 && target2.styles !== void 0 && target2.apiStatus !== "loading"
6227
6270
  );
6228
6271
  }
6272
+ function selectedAskSelection() {
6273
+ const snapshots = targets.flatMap((target2) => {
6274
+ const snapshot = snapshotTarget(target2);
6275
+ return snapshot === void 0 ? [] : [snapshot];
6276
+ });
6277
+ if (snapshots.length === 0 || snapshots.length !== targets.length) {
6278
+ return void 0;
6279
+ }
6280
+ return Object.freeze({
6281
+ locale: view.locale(),
6282
+ targets: snapshots
6283
+ });
6284
+ }
6229
6285
  function selectionSummary() {
6230
6286
  const messages = view.messages().summary;
6231
6287
  return targets.map((target2, index) => {
@@ -6347,6 +6403,7 @@ ${summary}`;
6347
6403
  api.cancelPending();
6348
6404
  agentWorkflow.disposeSelection();
6349
6405
  externalHandoffWorkflow?.cancelPending();
6406
+ contextualAskWorkflow?.cancelPending();
6350
6407
  clearCollectionTimers();
6351
6408
  resizeObserver?.disconnect();
6352
6409
  targets = [];
@@ -6472,6 +6529,27 @@ ${summary}`;
6472
6529
  config.sessionToken,
6473
6530
  browser.window
6474
6531
  ) : void 0;
6532
+ const contextualAskWorkflow = config.contextualAsk.enabled && view.contextualAskPanel !== void 0 ? getContextualAskExtension()?.createWorkflow({
6533
+ ...clipboard === void 0 ? {} : { clipboard },
6534
+ createId,
6535
+ fetch: browser.window.fetch.bind(browser.window),
6536
+ getSelection: selectedAskSelection,
6537
+ onBusyChange(busy) {
6538
+ view.setAgentEditingEnabled(!busy);
6539
+ },
6540
+ onConvert() {
6541
+ view.focusTargetInstruction(activeTargetId);
6542
+ },
6543
+ async onOpenSource(source2) {
6544
+ await api.openEditor({
6545
+ fileId: source2.fileId,
6546
+ line: source2.startLine,
6547
+ column: 1
6548
+ });
6549
+ },
6550
+ panel: view.contextualAskPanel,
6551
+ sessionToken: config.sessionToken
6552
+ }) : void 0;
6475
6553
  async function loadSourceContext(target2, revision) {
6476
6554
  const marker = target2.marker;
6477
6555
  if (marker === void 0) {
@@ -6585,6 +6663,7 @@ ${summary}`;
6585
6663
  previewPrompt = "";
6586
6664
  agentWorkflow.beginSelection();
6587
6665
  workflowSelectionActive = true;
6666
+ contextualAskWorkflow?.beginSelection();
6588
6667
  }
6589
6668
  targetSequence += 1;
6590
6669
  const target2 = {
@@ -6603,6 +6682,9 @@ ${summary}`;
6603
6682
  dataFlowStatus: "idle"
6604
6683
  };
6605
6684
  targets.push(target2);
6685
+ if (!initialSelection) {
6686
+ contextualAskWorkflow?.selectionChanged();
6687
+ }
6606
6688
  activeTargetId = target2.id;
6607
6689
  addingTarget = false;
6608
6690
  const revision = sessionRevision;
@@ -6719,10 +6801,12 @@ ${summary}`;
6719
6801
  pageDataFlowStatus = "idle";
6720
6802
  renderDataFlowView();
6721
6803
  selectionSession.clear();
6804
+ contextualAskWorkflow?.selectionChanged();
6722
6805
  view.announce(view.messages().announcements.allTargetsRemoved);
6723
6806
  return;
6724
6807
  }
6725
6808
  refreshSelectionView();
6809
+ contextualAskWorkflow?.selectionChanged();
6726
6810
  void loadDataFlowReports();
6727
6811
  persistSelection();
6728
6812
  view.announce(view.messages().announcements.targetRemoved);
@@ -6901,6 +6985,7 @@ ${summary}`;
6901
6985
  }
6902
6986
  mounted = true;
6903
6987
  externalHandoffWorkflow?.mount();
6988
+ contextualAskWorkflow?.mount();
6904
6989
  view.renderStatus(state.status);
6905
6990
  browser.document.addEventListener("pointermove", handlePointerMove, true);
6906
6991
  browser.document.addEventListener("click", handleClick, true);
@@ -6952,6 +7037,7 @@ ${summary}`;
6952
7037
  if (selectionOpen && targets.length > 0) {
6953
7038
  transition({ type: "RESTORE" });
6954
7039
  agentWorkflow.beginSelection();
7040
+ contextualAskWorkflow?.beginSelection();
6955
7041
  workflowSelectionActive = true;
6956
7042
  refreshSelectionView(true);
6957
7043
  }
@@ -6968,6 +7054,7 @@ ${summary}`;
6968
7054
  api.dispose();
6969
7055
  agentWorkflow.disposeSelection();
6970
7056
  externalHandoffWorkflow?.dispose();
7057
+ contextualAskWorkflow?.dispose();
6971
7058
  sourceResolver.dispose();
6972
7059
  return;
6973
7060
  }
@@ -7032,6 +7119,7 @@ ${summary}`;
7032
7119
  api.dispose();
7033
7120
  agentWorkflow.disposeSelection();
7034
7121
  externalHandoffWorkflow?.dispose();
7122
+ contextualAskWorkflow?.dispose();
7035
7123
  sourceResolver.dispose();
7036
7124
  view.dispose();
7037
7125
  state = INITIAL_RUNTIME_STATE;