Skip to main content

ContextBase

interface

Everything every handler in a mod can reach. The shape is a split: state and events are how you read the app, actions are how you change it. A mod never mutates host state directly. It dispatches an action, the host applies it, and the change comes back as state and events. That is what makes a mod's effect on the app inspectable in the causal trace. Each surface receives a context built on this one and adds what that surface has: CommandContext adds the invocation, ViewContext adds the rendering panel, SlashCommandContext adds the AI session, HostContext serves renderer-native code.

interface ContextBase

Import

import { ContextBase } from '@modular/sdk';

Members20

ai
AiRuntimeApi

One off answers, agents, models, and sessions.

completedActionTraces
ReadonlySignal<readonly HostActionTrace[]>

Traces of actions that have finished, for mods that show or verify what the app did. Pair it with ContextBase.subscribeActionTraces to be told when a new one lands.

hooks
HostHookClient

Register interceptors from code.

logger
Logger

Your mod's log channel.

media
MediaApi

Screen, camera, and audio capture.

modId
`${string}.${string}` & $brand<'ModId'>

The id of the mod this handler belongs to.

permissions
PermissionClient

What the user has granted, denied, and is being asked.

system
SystemCapabilities

Host event sources you can listen to, and the catalog to discover them.

terminal
TerminalApi

Create and drive terminals.

workbench
WorkbenchApi

The window shell: theme, layout, status bar, opening things.

workspace
WorkspaceApi

Folders, files, and configuration of the open workspace.

action
<K extends string>(id: K, input: ModularActionInput<K>, options?: HostActionClientRunOptions) => Promise<ModularActionResult<K>>

Dispatch an action. This is the only way a mod changes the app. Takes a host action id or a bare command id. Inside an event listener, prefer `occurrence.action(...)` so the causal link survives.

describeAction
(id: string) => ModularActionDescriptorDto | undefined

Look up one action's schema, or `undefined` if nothing owns that id.

describeEvent
(id: string) => ModularEventDescriptorDto | undefined

Look up one event's schema, or `undefined` if nothing declares that id.

emit
<TPayload>(descriptor: Event<TPayload>, payload: TPayload, options?: HostActionClientRunOptions) => Promise<EventEmitResult>

Publish one of your mod's own events to whoever is listening.

listActions
() => readonly ModularActionDescriptorDto[]

Every action available right now, including those other mods contribute.

listEvents
() => readonly ModularEventDescriptorDto[]

Every event you can subscribe to right now.

on
<TPayload>(descriptor: Event<TPayload>, listener: (event: EventOccurrence<TPayload>) => void | Promise<void>) => Disposable | <K extends ModularEventId>(id: K, listener: (event: EventOccurrence<ModularEventMap[K]>) => void | Promise<void>) => Disposable

Subscribe to an event, either your own declared one or a host event named by id. Dispose the result to stop listening.

state
<TValue>(declaration: StateDeclaration<TValue>) => OwnedState<TValue> | <TName extends 'editor.selection' | 'host.scope' | 'workbench.colorTheme' | 'workbench.layout' | 'workbench.windowState' | 'workspace.focusedEditorGroupTab'>(name: TName) => State<BuiltInStateValue<TName>>

Acquire a live state handle. Passing your own `state(...)` declaration gives an OwnedState you can write with `set`. Passing a built-in name gives a read-only State: host state changes only through actions.

subscribeActionTraces
(listener: () => void) => Disposable

Runs `listener` whenever a new trace lands in `completedActionTraces`.

Notes

category
Context