API reference
Choose interfaces by execution context. The declaration below is included directly from the current public SDK; match required permissions and the target host version.
Find an object
| Object | Purpose | Guide |
|---|---|---|
| ExtensionContext | Background commands, registrations, data, notifications and schedules | Concepts |
| ViewContext | UI, resources, clipboard, references, state and closing | Views |
| ResourceApi / LocalResourceApi | Read, create and export private or authorized files | Files |
| DocumentApi / EditableDocument | Content revisions, original saves and recovery | Documents |
| AgentToolContext / AgentActionContext | Original-task tools and independent actions | Agent |
| ReferenceInput / ReferenceReveal | Material snapshots and source reveal | References |
| WorkerApi | Packaged Worker lifecycle | Computation |
| EventSubscriber / TaskActionEvents | Scoped events and action causes | State |
Manifest fields
Extension.json requires schemaVersion 1, a stable id, name, version, apiVersion and engines.lexora. Format selects source/compiled. Provide entry when background code is needed. Declare permissions and contributions for actual capabilities; see Your first plugin.
Optional author attribution is independent of identity; icon points to a packaged image. DataVersion and a view's stateVersion govern separate migrations. Do not infer Lexora fields from another product's manifest.
Complete type declaration
Copy this declaration as lexora.d.ts and use import type. Independent SDK export uses the same source. A declared interface may require a newer host than the installed version.
Expand the public SDK types
export type Json = null | boolean | number | string | Json[] | { [key: string]: Json }
export type ReadonlyJson = string | number | boolean | null | ReadonlyJsonArray | ReadonlyJsonObject
export interface ReadonlyJsonArray extends ReadonlyArray<ReadonlyJson> {}
export interface ReadonlyJsonObject { readonly [key: string]: ReadonlyJson }
export interface Disposable { dispose: () => void | Promise<void> }
export interface EventSubscription { dispose: () => void }
export interface EventSubscriptionOptions { signal?: AbortSignal, once?: boolean }
export type EventName<Events> = Extract<keyof Events, string>
type NamespacePattern<Name extends string> = Name extends `${infer Head}:${infer Tail}` ? `${Head}:*` | `${Head}:**` | `${Head}:${NamespacePattern<Tail>}` : never
export type EventPattern<Events> = EventName<Events> | '*' | '**' | NamespacePattern<EventName<Events>>
type EventMatches<Name extends string, Pattern extends string> = Pattern extends '**' ? true
: Pattern extends `${infer Prefix}:**` ? Name extends Prefix | `${Prefix}:${string}` ? true : false
: Pattern extends `${infer Prefix}:*` ? Name extends `${Prefix}:${infer Tail}` ? Tail extends `${string}:${string}` ? false : true : false
: Pattern extends '*' ? Name extends `${string}:${string}` ? false : true : Name extends Pattern ? true : false
export type EventMessage<Events, Pattern extends string = '**'> = Pattern extends unknown ? {
[Name in EventName<Events>]: EventMatches<Name, Pattern> extends true ? Readonly<{ type: Name, data: Events[Name] }> : never
}[EventName<Events>] : never
export interface EventSubscriber<Events> {
on: <const Pattern extends EventPattern<Events>>(patterns: Pattern | readonly Pattern[], listener: (event: EventMessage<Events, Pattern>) => unknown, options?: EventSubscriptionOptions) => EventSubscription
}
export type EventSnapshot<Value> = Value extends object ? { readonly [Key in keyof Value]: EventSnapshot<Value[Key]> } : Value
export type FileOpeningLocation = 'inline' | 'standalone'
export type FileViewResource = 'selected-file' | 'optional-file' | 'none'
export interface FileHandlerView {
view: string
/** Preselect this mode in the installation dialog. Defaults to true. */
requestDefault?: boolean
}
export interface FileHandlerContribution {
id: string
title: string
extensions: string[]
preview?: FileHandlerView
open?: FileHandlerView
}
/** Legacy declaration. New plugins should use FileHandlerContribution. */
export interface FileOpenerContribution {
id: string
title: string
view: string
extensions: string[]
locations: FileOpeningLocation[]
requestDefault?: boolean
}
export interface LauncherContribution { id: string, title: string, view: string }
export interface NavigationContribution {
title: string
view: string
/** Show the host title bar on this navigation page. Defaults to true; does not affect resource tabs or the app frame. */
showHeader?: boolean
when?: WorkbenchCondition
}
/** API 4: contributes.skills; id is plugin-prefixed and package-wide unique; path points to a packaged Skill directory's SKILL.md. */
export interface SkillContribution { id: string, path: string }
/**
* API 4 increment: contributes.mcpConnectors; see mcp-connectors.md and set engines.lexora to verified supporting hosts.
* Independent declarations need no other contributions, entry or plugin permissions.
* Connection definitions follow the plugin; credentials, enablement and authorization remain host-managed.
*/
export interface McpConnectorContribution {
/** Unprefixed package-local ID matching /^[a-z0-9][a-z0-9_-]{0,63}$/, unique among MCP connectors; not a user connection ID. */
id: string
name: string
transport: 'streamable-http'
/** HTTPS address without userinfo or secrets. */
url: string
/** Required authentication requirement, not credentials or a guarantee of host OAuth support. */
authentication: 'none' | 'bearer' | 'oauth'
}
export type SubagentToolReference = {
source: 'mcp'
/** Local ID declared in this package's contributes.mcpConnectors. */
connector: string
/** Exact remote tool name, not a host-generated or JSON-encoded identity. */
name: string
} | {
source: 'builtin'
name: 'read' | 'find' | 'grep' | 'ls'
}
/**
* API 4 increment: contributes.subagents (NPC); see buddies.md and set engines.lexora to verified supporting hosts.
* Independent declarations need no MCP connectors, Skills, entry or plugin permissions and do not bind themselves to a companion.
* Enablement, model selection and companion bindings are user configuration, not manifest fields.
* Customize a copy; explicitly referenced plugin Skills and connectors remain dependencies of that copy.
*/
export interface SubagentContribution {
/** Unprefixed package-local ID matching /^[a-z0-9][a-z0-9_-]{0,63}$/, unique among NPCs; built-in NPC IDs are reserved. */
id: string
name: string
/** Defaults to ''. */
description?: string
instructions: string
/** Unique full plugin-prefixed contributes.skills IDs from this package. Defaults to []. */
skills?: string[]
/** Unique subset of skills that must be available. Defaults to []. */
requiredSkills?: string[]
/** Unique explicit references; no all-tools selection. Defaults to []. */
tools?: SubagentToolReference[]
/** Required. Inherits the task's limits or restricts file access; read_only forbids MCP references. */
fileAccess: 'inherit' | 'read_only'
}
export interface Resource { readonly id: string, readonly name: string, readonly sourceId?: string }
export interface ResourceTransferOptions { name?: string, signal?: AbortSignal }
export interface ResourceApi {
readText: (resource: Resource) => Promise<string>
listFiles: () => Promise<LocalFile[]>
getUrl: (resource: Pick<LocalFile, 'id'> | { packagePath: string }) => Promise<string>
readBytes: (resource: Pick<LocalFile, 'id'>, options?: { offset?: number, length?: number }) => Promise<{ data: Uint8Array, size: number, eof: boolean }>
importFile: (resource: Resource, options?: ResourceTransferOptions) => Promise<LocalFile>
createFile: (options: { name: string, data: Blob | ArrayBuffer | Uint8Array, mimeType?: string, signal?: AbortSignal }) => Promise<LocalFile>
release: (resource: Pick<LocalFile, 'id'>) => Promise<void>
}
export interface LocalFile extends Resource { readonly mimeType: string, readonly size: number, readonly relativePath?: string }
export interface LocalDirectory extends Resource {}
export interface LocalResourceApi extends ResourceApi {
pickFiles: (options?: { filters?: { name: string, extensions: string[] }[], multiple?: boolean }) => Promise<LocalFile[]>
revokeFile: (resource: Pick<LocalFile, 'id'>) => Promise<void>
pickDirectory: () => Promise<LocalDirectory | null>
listDirectories: () => Promise<LocalDirectory[]>
scanDirectory: (directory: Pick<LocalDirectory, 'id'>, options?: { extensions?: string[], recursive?: boolean }) => Promise<LocalFile[]>
revokeDirectory: (directory: Pick<LocalDirectory, 'id'>) => Promise<void>
saveFile: (options: { name: string, data: Blob | ArrayBuffer | Uint8Array }) => Promise<boolean>
}
export interface NetworkApi {
get: (url: string) => Promise<{ status: number, text: string }>
download: (url: string, options?: ResourceTransferOptions) => Promise<LocalFile>
}
export interface ScheduleInput { id: string, command: string, enabled: boolean, intervalMinutes: number }
export interface Schedule extends ScheduleInput { nextRunAt: number | null }
export interface ScheduleApi {
get: (id: string) => Promise<Schedule | null>
set: (schedule: ScheduleInput) => Promise<Schedule>
remove: (id: string) => Promise<void>
}
export interface CommandInvocation {
readonly target: 'composer.actions' | 'task.actions' | 'resource.actions' | 'message.actions' | 'view' | 'slash'
readonly instanceId: string | null
readonly content?: string
}
export interface Rect { readonly x: number, readonly y: number, readonly width: number, readonly height: number }
export interface PaneSnapshot { readonly id: string, readonly active: boolean, readonly visible: boolean, readonly rect: Rect }
export interface Interaction { readonly id: string, readonly signal: AbortSignal, end: () => Promise<void> }
export interface PlacementOptions { instanceId?: string, interactionId?: string }
export interface HitRegion { id: string, label: string, rect: Rect }
export interface ModelSelection { providerId: string, modelId: string }
export type SettingValue = boolean | string | number | ModelSelection | null
export interface ConfigurationEvents {
'configuration:changed': { readonly configuration: EventSnapshot<Record<string, SettingValue>>, readonly changedKeys: readonly string[] }
}
export interface WorkbenchPaneEvents {
'workbench:panes:changed': { readonly panes: readonly PaneSnapshot[] }
}
export interface ExtensionEvents extends ConfigurationEvents, WorkbenchPaneEvents {}
export interface TaskTitle {
id: string
title: string | null
titleSource: 'legacy' | 'manual' | 'fallback' | 'generated'
}
export interface AgentReferenceSummary { referenceId: string, sourceMessageId: string, title: string, excerpt: string }
export interface AgentReference {
referenceId: string
sourceMessageId: string
title: string
text: string
textLength: number
textDigest: string
offset: number
nextOffset: number | null
locator: ReferenceLocator | null
scope: { taskId: string, branchId: string }
}
export interface AgentPublishedArtifact { id: string, name: string, mimeType: string, size: number }
export interface AgentToolContext {
readonly scope: Readonly<{ taskId: string, branchId: string, runId: string }>
readonly artifacts: {
/** Publish a private file to this task. Requires a write tool. Creates an independent workspace copy and a task output card. */
publish: (input: { resource: Pick<LocalFile, 'id'>, name?: string }) => Promise<AgentPublishedArtifact>
}
readonly results: {
/** Add a private PNG/JPEG/WebP to this tool's native model image result. Await before returning the JSON result. */
addImage: (input: { resource: Pick<LocalFile, 'id'> }) => Promise<void>
}
readonly references: {
list: () => Promise<{ items: AgentReferenceSummary[], truncated: boolean }>
resolve: (referenceId: string, options?: { sourceMessageId?: string, offset?: number, limit?: number }) => Promise<AgentReference>
}
readonly signal: AbortSignal
readonly task: {
get: () => Promise<TaskTitle>
messages: () => Promise<{ role: 'user' | 'assistant', text: string }[]>
rename: (input: { title: string }) => Promise<{ applied: boolean }>
}
readonly models: {
generateText: (input: { prompt: string, system?: string, model?: ModelSelection | null, maxTokens?: number }) => Promise<{ text: string, model: ModelSelection }>
}
}
export interface TaskActionEvents {
'task:created': { readonly conversationId: string, readonly branchId: string, readonly runId: string, readonly messageId: string, readonly commitId: string }
'task:run:before': { readonly conversationId: string, readonly branchId: string, readonly runId: string, readonly messageId: string }
'task:reply:started': { readonly conversationId: string, readonly branchId: string, readonly runId: string, readonly messageId: string }
'task:input:committed': { readonly conversationId: string, readonly branchId: string, readonly runId: string, readonly messageId: string, readonly commitId: string }
'task:turn:completed': { readonly conversationId: string, readonly branchId: string, readonly runId: string, readonly triggeringMessageId: string, readonly completedAt: string }
}
export interface AgentActionContext extends Omit<AgentToolContext, 'references' | 'scope' | 'artifacts' | 'results'> {
readonly cause: EventMessage<TaskActionEvents> | Readonly<{ type: 'user' }>
}
export interface AgentActionResult { status: 'completed' | 'skipped', message?: string }
export type ConditionInput = 'configuration' | 'runtime.models' | 'runtime.task' | 'workbench' | 'form'
export interface ConditionReference { condition: string, params?: ReadonlyJsonObject }
export interface ConditionResult { value: boolean, reason?: string }
export type ConfigurationScope = { kind: 'global' } | { kind: 'space', spaceId: string } | { kind: 'task', taskId: string }
export type ConditionInvocationScope = { kind: 'settings', moduleId: string, groupId: string } | { kind: 'task', taskId: string, runId: string | null }
export type ConditionData<T> = EventSnapshot<{ status: 'available', revision: string } & T> | Readonly<{ status: 'not_requested' | 'no_context' | 'denied' | 'unsupported' | 'loading' | 'invalid' }>
export interface ConditionContext {
readonly version: 1
readonly signal: AbortSignal
readonly scope: EventSnapshot<{ key: string, configuration: ConfigurationScope, invocation: ConditionInvocationScope }>
readonly target: Readonly<{ kind: 'setting' | 'agent' | 'action', id: string }>
readonly configuration: ConditionData<{ values: Record<string, SettingValue>, sources: Record<string, ConfigurationScope> }>
readonly runtime: Readonly<{
models: ConditionData<{ selection: ModelSelection | null, models: { providerId: string, modelId: string, name: string, available: boolean, capabilities: string[] }[] }>
task: ConditionData<{ id: string, spaceId: string | null, branchId: string, title: string | null, titleSource: 'fallback' | 'generated' | 'manual' | 'legacy', activity: 'idle' | 'running' | 'awaiting_approval', modelSelection: ModelSelection | null }>
}>
readonly workbench: ConditionData<{ panes: { id: string, active: boolean, visible: boolean }[] }>
readonly form: ConditionData<{ values: Record<string, SettingValue>, dirtyKeys: string[] }>
}
export interface ConditionApi {
register: (id: string, evaluate: (context: ConditionContext, params: ReadonlyJsonObject) => boolean | ConditionResult | Promise<boolean | ConditionResult>) => Disposable
invalidate: (input?: { condition?: string, scopeKey?: string }) => Promise<void>
}
export type ShellCandidateId = 'bash' | 'git-bash' | 'zsh' | 'sh' | 'powershell7' | 'powershell51' | 'cmd'
export interface ShellCandidate {
id: ShellCandidateId
label: string
dialect: 'bash' | 'zsh' | 'sh' | 'powershell' | 'cmd'
executable: string
version: string
available: boolean
reason?: string
}
export interface WorkerOptions {
type?: 'classic' | 'module'
name?: string
signal?: AbortSignal
}
export interface WorkerApi {
create: (entry: string | URL, options?: WorkerOptions) => Promise<Worker>
}
export interface ExtensionContext {
readonly signal: AbortSignal
readonly workers: WorkerApi
readonly themes: ThemeApi
readonly extension: { readonly id: string, readonly version: string, readonly apiVersion: 1 | 2 | 3 | 4 }
readonly events: EventSubscriber<ExtensionEvents>
readonly configuration: {
get: () => Promise<Record<string, SettingValue>>
onChange: (listener: (configuration: Readonly<Record<string, SettingValue>>) => void | Promise<void>) => Disposable
}
readonly conditions: ConditionApi
readonly shells: { detect: () => Promise<ShellCandidate[]> }
readonly agent: {
registerTool: (id: string, execute: (input: Record<string, Json>, context: AgentToolContext) => Json | void | Promise<Json | void>) => Disposable
registerAction: (id: string, execute: (context: AgentActionContext) => AgentActionResult | Promise<AgentActionResult>) => Disposable
}
readonly subscriptions: { add: <T extends Disposable>(disposable: T) => T }
readonly commands: { register: (id: string, execute: (context: { resource: Resource | null, arguments: Json, invocation: CommandInvocation | null }) => Json | void | Promise<Json | void>) => Disposable }
readonly placements: { show: (id: string, options?: string | PlacementOptions) => Promise<string>, hide: (id: string, options?: string | PlacementOptions) => Promise<string | null> }
readonly window: { readonly styles: { set: (id: string, css: string) => Promise<void>, remove: (id: string) => Promise<void> } }
readonly workbench: { readonly panes: readonly PaneSnapshot[], onPanesChange: (listener: (panes: readonly PaneSnapshot[]) => void) => Disposable }
readonly interactions: { start: (title: string) => Promise<Interaction> }
readonly views: { broadcast: (message: Json) => Promise<void>, open: (type: string, options?: { resource?: Resource | null, state?: Json }) => Promise<string> }
readonly resources: ResourceApi
readonly network: NetworkApi
readonly storage: { get: () => Promise<Json>, set: (value: Json) => Promise<void> }
readonly notifications: { show: (notification: { title: string, body: string }) => Promise<boolean> }
readonly schedules: ScheduleApi
}
export type WorkbenchRegion
= | 'window'
| 'app.sidebar'
| 'workbench.sidebar'
| 'workbench.workspace'
| 'workbench.pane'
| 'task.history'
| 'composer.input'
export interface AnchorGeometry {
readonly kind: WorkbenchRegion
readonly visible: boolean
readonly width: number
readonly height: number
}
export interface ControlSnapshot {
readonly revision: string
readonly value: string | null
readonly options: readonly { readonly value: string, readonly label: string }[]
readonly disabled: boolean
}
export type MountTarget = 'workbench' | 'app.sidebar' | 'workbench.sidebar' | 'workbench.pane'
export type MountLength = number | `${number}%` | null
export interface ViewPresentation {
target?: MountTarget
position?: 'static' | 'absolute'
order?: number
zIndex?: number
width?: MountLength
height?: MountLength
top?: MountLength
right?: MountLength
bottom?: MountLength
left?: MountLength
}
export interface MountGeometry {
readonly instanceId?: string
readonly target: MountTarget
readonly visible: boolean
readonly width: number
readonly height: number
readonly rect: { readonly x: number, readonly y: number, readonly width: number, readonly height: number }
}
export type WorkbenchContextValues = Readonly<Record<string, string | number | boolean>>
export type WorkbenchCondition = Record<string, string | number | boolean | (string | number | boolean)[]>
export interface WorkbenchContextSnapshot {
readonly values: WorkbenchContextValues
readonly pages: readonly { readonly id: string, readonly title: string }[]
}
export interface ReferenceLocator {
readonly version: number
readonly data: ReadonlyJson
}
export type ReferenceChoice = { kind: 'view', id: string } | { kind: 'new-task' | 'clipboard' }
export interface ReferenceCapture {
readonly id: string
readonly targets: readonly { readonly id: string, readonly label: string }[]
readonly defaultId: string | null
readonly clipboard: boolean
}
export interface ReferenceReveal {
readonly referenceId: string
readonly text: string
readonly locator: ReferenceLocator | null
}
export type ReferenceInput
= | { kind: 'content', title: string, text: string, locator?: ReferenceLocator, source?: 'view' }
| { kind: 'resource', resource: { id: string } }
/** Format-independent editable content; it may exist before a file is saved. */
export interface EditableDocument {
readonly id: string
readonly name: string
readonly location: string
readonly version: string | null
readonly revision: string
readonly size: number
readonly writable: boolean
readonly kind: 'file' | 'draft'
readonly recovery: boolean
readonly openedAt: number
}
export interface DocumentBytes { data: Blob | ArrayBuffer | Uint8Array, signal?: AbortSignal }
export interface DocumentApi {
pick: (options?: { filters?: { name: string, extensions: string[] }[] }) => Promise<EditableDocument | null>
open: (resource: Resource) => Promise<EditableDocument | null>
resume: (document: Pick<EditableDocument, 'id'>) => Promise<EditableDocument>
list: () => Promise<EditableDocument[]>
read: (document: Pick<EditableDocument, 'id'>, options?: { recovery?: boolean, signal?: AbortSignal }) => Promise<Uint8Array>
create: (options: DocumentBytes & { name: string }) => Promise<EditableDocument>
save: (document: EditableDocument, options: DocumentBytes) => Promise<EditableDocument>
saveAs: (options: DocumentBytes & { name: string }) => Promise<EditableDocument | null>
backup: (document: EditableDocument, options: DocumentBytes) => Promise<EditableDocument>
status: (document: Pick<EditableDocument, 'id'>) => Promise<{ changed: boolean }>
discardRecovery: (document: Pick<EditableDocument, 'id'>) => Promise<void>
close: (document: Pick<EditableDocument, 'id'>) => Promise<void>
forget: (document: Pick<EditableDocument, 'id'>) => Promise<void>
reveal: (document: Pick<EditableDocument, 'id'>) => Promise<void>
}
export type ExtensionDataSource = 'task.metrics' | 'context.usage'
export interface ExtensionDataQuery<Source extends ExtensionDataSource = ExtensionDataSource> {
readonly source: Source
readonly scope: 'bound'
}
export interface ExtensionDataValues {
'task.metrics': {
taskId: string
branchId: string
turns: number
steps: number
tokens: { inputTokens: number, outputTokens: number, cacheReadTokens: number, cacheWriteTokens: number }
throughput: { samples: number, tokensPerSecond: number | null }
}
'context.usage': {
taskId: string
branchId: string
actorId: string
runId: string | null
tokens: number
window: number
percent: number
}
}
export type ExtensionDataSnapshot<Source extends ExtensionDataSource = ExtensionDataSource> = {
[Key in Source]: {
readonly source: Key
readonly status: 'ready'
readonly value: EventSnapshot<ExtensionDataValues[Key]>
} | {
readonly source: Key
readonly status: 'denied' | 'no_target' | 'unavailable'
readonly value: null
}
}[Source]
export interface ExtensionDataApi {
read: <Source extends ExtensionDataSource>(query: ExtensionDataQuery<Source>) => Promise<ExtensionDataSnapshot<Source>>
observe: <Source extends ExtensionDataSource>(query: ExtensionDataQuery<Source>, listener: (snapshot: ExtensionDataSnapshot<Source>) => unknown) => Disposable
}
export interface ViewContext {
readonly documents: DocumentApi
readonly clipboard: {
read: () => Promise<{ text?: string, html?: string }>
write: (data: { text?: string, html?: string }) => Promise<void>
}
setDocumentInfo: (info: { title: string, dirty: boolean }) => Promise<void>
onBeforeClose: (handler: (signal: AbortSignal) => boolean | Promise<boolean>) => Disposable
readonly workers: WorkerApi
readonly themes: ThemeApi
readonly events: EventSubscriber<ViewEvents>
readonly interaction: {
readonly id: string
setRegions: (regions: readonly HitRegion[]) => Promise<void>
onActivate: (listener: (event: { readonly id: string, readonly x: number, readonly y: number }) => void) => Disposable
} | null
onMessage: (listener: (message: Json) => void) => Disposable
readonly instanceId: string | null
readonly data: ExtensionDataApi
readonly workbench: WorkbenchContextSnapshot
onWorkbenchChange: (listener: (snapshot: WorkbenchContextSnapshot) => void) => Disposable
readonly visible: boolean
onVisibilityChange: (listener: (visible: boolean) => void) => Disposable
readonly mount: MountGeometry | null
onMountChange: (listener: (mount: MountGeometry) => void) => Disposable
readonly anchor: AnchorGeometry | null
onAnchorChange: (listener: (anchor: AnchorGeometry) => void) => Disposable
readonly control: {
readonly snapshot: ControlSnapshot
onChange: (listener: (snapshot: ControlSnapshot) => void) => Disposable
propose: (value: string, revision?: string) => Promise<void>
} | null
readonly environment: ViewEnvironment
onEnvironmentChange: (listener: (environment: ViewContext['environment']) => void) => Disposable
readonly apiVersion: 1 | 2 | 3 | 4
readonly resource: Resource | null
readonly state: Json
readonly stateVersion: number
readonly expectedStateVersion: number
readonly signal: AbortSignal
onActivity: (listener: (event: { readonly type: 'composer-input', readonly caret?: { readonly x: number, readonly y: number, readonly width: number, readonly height: number } | null }) => void) => Disposable
openExternal: (url: string) => Promise<void>
readonly references: {
add: (input: ReferenceInput) => Promise<boolean>
capture: (input: ReferenceInput) => Promise<ReferenceCapture | null>
commit: (id: string, choice: ReferenceChoice) => Promise<boolean>
release: (id: string) => Promise<boolean>
onReveal: (handler: (input: ReferenceReveal, signal: AbortSignal) => boolean | Promise<boolean>) => Disposable
}
readonly resources: LocalResourceApi
readonly network: NetworkApi
readonly commands: { execute: (command: string, args?: Json) => Promise<Json> }
setPresentation: (presentation: ViewPresentation) => Promise<void>
setState: (state: Json) => Promise<void>
setActive: (active: boolean) => Promise<void>
}
export interface ViewEnvironment {
readonly language: string
readonly colorScheme: 'light' | 'dark'
readonly themeRevision?: number
readonly colors: Readonly<Record<string, string>>
}
export interface ExtensionDataEvents {
'data:changed': { readonly id: string, readonly snapshot: ExtensionDataSnapshot | null }
}
export interface ViewStateEvents {
'view:visibility:changed': { readonly visible: boolean }
'view:environment:changed': { readonly environment: ViewEnvironment }
}
export interface ViewGeometryEvents {
'view:mount:changed': { readonly mount: MountGeometry }
'view:anchor:changed': { readonly anchor: AnchorGeometry }
}
export interface ViewMessageEvents {
'view:message:received': { readonly message: ReadonlyJson }
}
export interface WorkbenchContextEvents {
'workbench:context:changed': { readonly context: WorkbenchContextSnapshot }
}
export interface ControlEvents {
'control:changed': { readonly control: ControlSnapshot }
}
export interface InteractionEvents {
'interaction:activated': { readonly regionId: string, readonly x: number, readonly y: number }
}
export interface ComposerEvents {
'composer:input:received': { readonly caret?: Rect | null }
}
export interface ViewEvents extends ExtensionDataEvents, ViewStateEvents, ViewGeometryEvents, ViewMessageEvents, WorkbenchContextEvents, ControlEvents, InteractionEvents, ComposerEvents {}
export interface ExtensionModule {
activate: (context: ExtensionContext) => void | Promise<void>
deactivate?: () => void | Promise<void>
migrate?: (previous: Json, from: number, to: number) => Json | Promise<Json>
}
export interface ViewModule { render: (context: ViewContext, container: HTMLElement) => void | Promise<void> }
export type ThemeColor = 'app-sidebar-fg' | 'workspace-sidebar-fg' | 'reading' | 'reading-fg' | 'composer' | 'composer-fg' | 'hover-fg' | 'selected-fg' | 'pressed-fg' | 'link' | 'quote' | 'quote-border' | 'inline-code' | 'inline-code-fg' | 'code' | 'code-fg' | 'code-header' | 'code-border' | 'code-line-number' | 'table-header' | 'table-border' | 'table-stripe' | 'table-hover' | 'canvas-grid' | 'diff-added' | 'diff-removed' | 'editor' | 'editor-fg' | 'editor-line' | 'editor-gutter' | 'editor-cursor' | 'syntax-comment' | 'syntax-keyword' | 'syntax-string' | 'syntax-number' | 'syntax-function' | 'syntax-type' | 'syntax-variable' | 'syntax-operator' | 'terminal-background' | 'terminal-foreground' | 'terminal-muted' | 'terminal-scrollbar' | 'terminal-mauve' | 'terminal-blue' | 'terminal-green' | 'terminal-yellow' | 'terminal-peach' | 'terminal-maroon' | 'terminal-sky' | 'terminal-rosewater' | 'canvas' | 'app-sidebar' | 'workspace-sidebar' | 'surface' | 'raised' | 'subtle' | 'user-message' | 'hover' | 'pressed' | 'selected' | 'selected-hover' | 'nav-hover' | 'nav-selected' | 'nav-selected-hover' | 'nav-pressed' | 'nav-foreground' | 'border' | 'border-strong' | 'strong' | 'fg' | 'muted' | 'disabled' | 'on-accent' | 'accent' | 'accent-hover' | 'accent-pressed' | 'accent-text' | 'focus' | 'text-selection' | 'text-selection-inactive' | 'text-selection-match' | 'accent-subtle' | 'accent-surface' | 'accent-surface-hover' | 'accent-surface-pressed' | 'accent-border' | 'accent-border-hover' | 'accent-on-surface' | 'success' | 'success-solid' | 'success-surface' | 'success-surface-hover' | 'success-border' | 'warning' | 'warning-solid' | 'warning-surface' | 'warning-surface-hover' | 'warning-border' | 'danger' | 'danger-solid' | 'danger-surface' | 'danger-surface-hover' | 'danger-border' | 'gold' | 'gold-surface' | 'avatar' | 'avatar-foreground' | 'data-violet' | 'data-cyan' | 'data-blue'
export type ThemeAppearance = 'light' | 'dark'
export interface FileIconAssociations {
file?: string
folder?: string
folderExpanded?: string
rootFolder?: string
rootFolderExpanded?: string
fileNames?: Record<string, string>
fileExtensions?: Record<string, string>
languageIds?: Record<string, string>
folderNames?: Record<string, string>
folderNamesExpanded?: Record<string, string>
rootFolderNames?: Record<string, string>
rootFolderNamesExpanded?: Record<string, string>
}
export interface FileIconThemeDocument extends FileIconAssociations {
$schema?: string
iconDefinitions: Record<string, { iconPath: string }>
light?: FileIconAssociations
highContrast?: FileIconAssociations
hidesExplorerArrows?: boolean
}
export interface FileIconThemeContribution { id: string, label: string, path: string }
export interface ThemePreference { id: string }
export interface ThemeDescriptor { id: string, label: string, appearance: ThemeAppearance, source: 'plugin' | 'user' | 'fallback', extensionId: string | null, packageName: string, swatch: string }
export interface ThemeMaterial {
anchor: WorkbenchRegion
image?: string
color?: string
gradient?: { angle: number, stops: { color: string, at: number }[] }
opacity?: number
imageOpacity?: number
scale?: number
blur?: number
position?: [number, number]
size?: 'cover' | 'contain'
}
export interface ThemeDocument {
schemaVersion: 1
colors?: Partial<Record<ThemeColor, string>>
shadows?: Partial<Record<'soft' | 'raised' | 'overlay' | 'window' | 'illustration', { x: number, y: number, blur: number, spread?: number, color: string }[]>>
materials?: ThemeMaterial[]
welcome?: { text?: { 'zh-CN': string, 'en-US': string } | null, image?: string | null }
}
export interface ThemeArchive { schemaVersion: 1, label: string, appearance: ThemeAppearance, document: ThemeDocument, assets?: Record<string, string | { resourceId: string } | { packagePath: string }> }
export interface ResolvedTheme { descriptor: ThemeDescriptor, colors: Record<ThemeColor, string>, variables: Record<string, string>, document: ThemeDocument, assets: Record<string, string> }
export interface ThemeSnapshot { revision: number, preference: ThemePreference, active: ResolvedTheme, themes: ThemeDescriptor[], unavailable: string | null, preview: boolean }
export interface ThemePreview { token: string, revision: number }
export interface ThemeApi {
list: () => Promise<ThemeDescriptor[]>
get: (id: string) => Promise<{ descriptor: ThemeDescriptor, document: ThemeDocument }>
getActive: () => Promise<ThemeSnapshot>
describe: () => Promise<{ schema: Json, colors: ThemeColor[], anchors: ThemeMaterial['anchor'][], precedence: string[] }>
validate: (document: unknown) => Promise<{ valid: boolean, diagnostics: { path: string, message: string }[] }>
resolve: (appearance: ThemeAppearance, document: ThemeDocument, overrides?: Partial<Record<ThemeColor, string>>) => Promise<ResolvedTheme>
save: (archive: ThemeArchive, id?: string) => Promise<ThemeDescriptor>
remove: (id: string) => Promise<void>
setPreference: (preference: ThemePreference) => Promise<ThemeSnapshot>
beginPreview: (archive: ThemeArchive) => Promise<ThemePreview>
updatePreview: (preview: ThemePreview, archive: ThemeArchive) => Promise<ThemePreview>
commitPreview: (preview: ThemePreview) => Promise<ThemeDescriptor>
cancelPreview: (token: string) => Promise<void>
import: (content: string) => Promise<ThemeDescriptor>
export: (id: string) => Promise<string>
onDidChange: (listener: (snapshot: ThemeSnapshot) => void) => Disposable
}Errors and compatibility
Asynchronous APIs return promises. Cancellation may return a value or reject depending on the method. Save conflicts, revoked authorization and expired views are not success. Model truncation rejects with EXTENSION_MODEL_TRUNCATED rather than presenting incomplete text as a completed answer.
Check Permissions and compatibility and verify critical flows on your target host before upgrading.