/**
* Fresh Editor TypeScript Plugin API
*
* This file provides type definitions for the Fresh editor's TypeScript plugin system.
* Plugins have access to the global `editor` object which provides methods to:
* - Query editor state (buffers, cursors, viewports)
* - Modify buffer content (insert, delete text)
* - Add visual decorations (overlays, highlighting)
* - Interact with the editor UI (status messages, prompts)
*
* AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
* Generated by fresh-plugin-api-macros + ts-rs from JsEditorApi impl
*/
/**
* Get the editor API instance.
* Plugins must call this at the top of their file to get a scoped editor object.
*/
declare function getEditor(): EditorAPI;
/**
* Register a function as a named handler on the global scope.
*
* Handler functions registered this way can be referenced by name in
* `editor.registerCommand()`, `editor.on()`, and mode keybindings.
*
* The `fn` parameter is typed as `Function` because the runtime passes
* different argument shapes depending on the caller: command handlers
* receive no arguments, event handlers receive an event-specific data
* object (e.g. `{ buffer_id: number }`), and prompt handlers receive
* `{ prompt_type: string, input: string }`. Type-annotate your handler
* parameters to match the event you are handling.
*
* @param name - Handler name (referenced by registerCommand, on, etc.)
* @param fn - The handler function
*/
declare function registerHandler(name: string, fn: Function): void;
/** Handle for a cancellable async operation */
interface ProcessHandle<T> extends PromiseLike<T> {
	/** Promise that resolves to the result when complete */
	readonly result: Promise<T>;
	/** Cancel/kill the operation. Returns true if cancelled, false if already completed */
	kill(): Promise<boolean>;
}
/** Buffer identifier */
type BufferId = number;
/** Split identifier */
type SplitId = number;
/**
* Payload delivered to handlers registered with `editor.on("mouse_click", ...)`.
*
* All coordinate fields are in cell (terminal character) units. `buffer_*`
* fields are `null` when the click did not land in any buffer panel.
*/
interface MouseClickHookArgs {
	/** Screen column (0-indexed). */
	column: number;
	/** Screen row (0-indexed). */
	row: number;
	/** Mouse button: "left", "right", "middle". */
	button: string;
	/** Modifier keys (e.g. "shift"). */
	modifiers: string;
	/** X offset of the content area the click landed in. */
	content_x: number;
	/** Y offset of the content area the click landed in. */
	content_y: number;
	/** Buffer under the click, or `null` when outside any buffer panel. */
	buffer_id: number | null;
	/** 0-indexed buffer row (line number) of the click, accounting for scroll. */
	buffer_row: number | null;
	/** 0-indexed byte column inside the buffer row. */
	buffer_col: number | null;
}
/**
* Registry of typed plugin APIs surfaced through
* `editor.exportPluginApi` / `editor.getPluginApi`.
*
* Plugins that want their surface to be typed for downstream
* consumers augment this interface in their own source:
*
* ```ts
* // in my_plugin.ts
* export type MyPluginApi = { doThing(): void };
* declare global {
*   interface FreshPluginRegistry {
*     "my-plugin": MyPluginApi;
*   }
* }
* ```
*
* `editor.getPluginApi("my-plugin")` then returns
* `MyPluginApi | null` without any `as`-cast on the consumer side.
* Plugins that skip the augmentation still work — the untyped
* `getPluginApi<T = unknown>(name: string): T | null` overload
* takes over.
*
* Each plugin's augmentation is emitted to
* `<config_dir>/types/plugins.d.ts` at load time (via oxc's
* isolated-declarations), so init.ts sees every loaded plugin's
* registry entry automatically.
*/
interface FreshPluginRegistry {}
type TextPropertyEntry = {
	/**
	* Text content for this entry
	*/
	text: string;
	/**
	* Optional properties attached to this text (e.g., file path, line number)
	*/
	properties?: Record<string, unknown>;
	/**
	* Optional whole-entry styling
	*/
	style?: Partial<OverlayOptions>;
	/**
	* Optional sub-range styling within this entry
	*/
	inlineOverlays?: Array<InlineOverlay>;
};
type TsCompositeLayoutConfig = {
	/**
	* Layout type: "side-by-side", "stacked", or "unified"
	*/
	type: string;
	/**
	* Width ratios for side-by-side (e.g., [0.5, 0.5])
	*/
	ratios?: Array<number>;
	/**
	* Show separator between panes
	*/
	showSeparator: boolean;
	/**
	* Spacing for stacked layout
	*/
	spacing?: number;
};
type TsCompositeSourceConfig = {
	/**
	* Buffer ID of the source buffer (required)
	*/
	bufferId: number;
	/**
	* Label for this pane (e.g., "OLD", "NEW")
	*/
	label: string;
	/**
	* Whether this pane is editable
	*/
	editable: boolean;
	/**
	* Style configuration
	*/
	style: TsCompositePaneStyle | null;
};
type TsCompositePaneStyle = {
	/**
	* Background color for added lines (RGB)
	* Using [u8; 3] instead of (u8, u8, u8) for better rquickjs_serde compatibility
	*/
	addBg?: [number, number, number];
	/**
	* Background color for removed lines (RGB)
	*/
	removeBg?: [number, number, number];
	/**
	* Background color for modified lines (RGB)
	*/
	modifyBg?: [number, number, number];
	/**
	* Gutter style: "line-numbers", "diff-markers", "both", or "none"
	*/
	gutterStyle?: string;
};
type TsCompositeHunk = {
	/**
	* Starting line in old buffer (0-indexed)
	*/
	oldStart: number;
	/**
	* Number of lines in old buffer
	*/
	oldCount: number;
	/**
	* Starting line in new buffer (0-indexed)
	*/
	newStart: number;
	/**
	* Number of lines in new buffer
	*/
	newCount: number;
};
type TsCreateCompositeBufferOptions = {
	/**
	* Buffer name (displayed in tabs/title)
	*/
	name: string;
	/**
	* Mode for keybindings
	*/
	mode: string;
	/**
	* Layout configuration
	*/
	layout: TsCompositeLayoutConfig;
	/**
	* Source pane configurations
	*/
	sources: Array<TsCompositeSourceConfig>;
	/**
	* Diff hunks for alignment (optional)
	*/
	hunks: Array<TsCompositeHunk> | null;
	/**
	* When set, the first render will scroll to center the Nth hunk (0-indexed).
	* This avoids timing issues with imperative scroll commands that depend on
	* render-created state (viewport dimensions, view state).
	*/
	initialFocusHunk?: number;
};
type ViewportInfo = {
	/**
	* Byte position of the first visible line
	*/
	topByte: number;
	/**
	* Line number of the first visible line (None when line index unavailable, e.g. large file before scan)
	*/
	topLine: number | null;
	/**
	* Left column offset (horizontal scroll)
	*/
	leftColumn: number;
	/**
	* Viewport width
	*/
	width: number;
	/**
	* Viewport height
	*/
	height: number;
};
type LayoutHints = {
	/**
	* Optional compose width for centering/wrapping
	*/
	composeWidth?: number;
	/**
	* Optional column guides for aligned tables
	*/
	columnGuides?: Array<number>;
};
type ViewTokenWire = {
	/**
	* Source byte offset in the buffer. None for injected content (annotations).
	*/
	source_offset: number | null;
	/**
	* The token content
	*/
	kind: ViewTokenWireKind;
	/**
	* Optional styling for injected content (only used when source_offset is None)
	*/
	style?: ViewTokenStyle;
};
type ViewTokenWireKind = {
	"Text": string;
} | "Newline" | "Space" | "Break" | {
	"BinaryByte": number;
};
type ViewTokenStyle = {
	/**
	* Foreground color as RGB tuple
	*/
	fg: [number, number, number] | null;
	/**
	* Background color as RGB tuple
	*/
	bg: [number, number, number] | null;
	/**
	* Whether to render in bold
	*/
	bold: boolean;
	/**
	* Whether to render in italic
	*/
	italic: boolean;
};
type PromptSuggestion = {
	/**
	* The text to display
	*/
	text: string;
	/**
	* Optional description
	*/
	description?: string;
	/**
	* The value to use when selected (defaults to text if None)
	*/
	value?: string;
	/**
	* Whether this suggestion is disabled (greyed out, defaults to false)
	*/
	disabled?: boolean;
	/**
	* Optional keyboard shortcut
	*/
	keybinding?: string;
};
type DirEntry = {
	/**
	* File/directory name
	*/
	name: string;
	/**
	* True if this is a file
	*/
	is_file: boolean;
	/**
	* True if this is a directory
	*/
	is_dir: boolean;
};
type BufferInfo = {
	/**
	* Buffer ID
	*/
	id: number;
	/**
	* File path (if any)
	*/
	path: string;
	/**
	* Whether the buffer has been modified
	*/
	modified: boolean;
	/**
	* Length of buffer in bytes
	*/
	length: number;
	/**
	* Whether this is a virtual buffer (not backed by a file)
	*/
	is_virtual: boolean;
	/**
	* Current view mode of the active split: "source" or "compose"
	*/
	view_mode: string;
	/**
	* True if any split showing this buffer has compose mode enabled.
	* Plugins should use this (not `view_mode`) to decide whether to maintain
	* decorations, since decorations live on the buffer and are filtered
	* per-split at render time.
	*/
	is_composing_in_any_split: boolean;
	/**
	* Compose width (if set), from the active split's view state
	*/
	compose_width: number | null;
	/**
	* The detected language for this buffer (e.g., "rust", "markdown", "text")
	*/
	language: string;
	/**
	* Whether this tab was opened in "preview" (ephemeral) mode — true when
	* opened via single-click in the file explorer and not yet committed
	* (no edit, no double-click, no tab-click, no layout change). Plugins
	* that react to buffer lifecycle events should generally treat preview
	* buffers as transient; e.g. a diagnostics panel may want to skip
	* refreshing itself for a preview tab.
	*/
	is_preview: boolean;
	/**
	* Split ids that currently hold this buffer (empty when the buffer is
	* open but not visible in any split — e.g. background-opened tabs
	* that haven't been focused). Lets plugins implement "focus existing
	* buffer if visible, else open new" without having to track split
	* ids across editor restarts (which reassign them). The list is a
	* snapshot at the last `update_plugin_state_snapshot` tick.
	*/
	splits: number[];
};
type JsDiagnostic = {
	/**
	* Document URI
	*/
	uri: string;
	/**
	* Diagnostic message
	*/
	message: string;
	/**
	* Severity: 1=Error, 2=Warning, 3=Info, 4=Hint, null=unknown
	*/
	severity: number | null;
	/**
	* Range in the document
	*/
	range: JsRange;
	/**
	* Source of the diagnostic (e.g., "typescript", "eslint")
	*/
	source?: string;
};
type JsRange = {
	/**
	* Start position
	*/
	start: JsPosition;
	/**
	* End position
	*/
	end: JsPosition;
};
type JsPosition = {
	/**
	* Zero-indexed line number
	*/
	line: number;
	/**
	* Zero-indexed character offset
	*/
	character: number;
};
type ActionSpec = {
	/**
	* Action name (e.g., "move_word_right", "delete_line")
	*/
	action: string;
	/**
	* Number of times to repeat the action (default 1)
	*/
	count: number;
};
type TsActionPopupAction = {
	/**
	* Unique action identifier (returned in ActionPopupResult)
	*/
	id: string;
	/**
	* Display text for the button (can include command hints)
	*/
	label: string;
};
type ActionPopupOptions = {
	/**
	* Unique identifier for the popup (used in ActionPopupResult)
	*/
	id: string;
	/**
	* Title text for the popup
	*/
	title: string;
	/**
	* Body message (supports basic formatting)
	*/
	message: string;
	/**
	* Action buttons to display
	*/
	actions: Array<TsActionPopupAction>;
};
type FileExplorerDecoration = {
	/**
	* File path to decorate
	*/
	path: string;
	/**
	* Symbol to display (e.g., "●", "M", "A")
	*/
	symbol: string;
	/**
	* Color as RGB array or theme key string (e.g., "ui.file_status_added_fg")
	*/
	color: OverlayColorSpec;
	/**
	* Priority for display when multiple decorations exist (higher wins)
	*/
	priority: number;
};
type FormatterPackConfig = {
	/**
	* Command to run (e.g., "prettier", "rustfmt")
	*/
	command: string;
	/**
	* Arguments to pass to the formatter
	*/
	args: Array<string>;
};
type ProcessLimitsPackConfig = {
	/**
	* Maximum memory usage as percentage of total system memory (null = no limit)
	*/
	maxMemoryPercent: number | null;
	/**
	* Maximum CPU usage as percentage of total CPU (null = no limit)
	*/
	maxCpuPercent: number | null;
	/**
	* Enable resource limiting
	*/
	enabled: boolean | null;
};
type TerminalResult = {
	/**
	* The created buffer ID (for use with setSplitBuffer, etc.)
	*/
	bufferId: number;
	/**
	* The terminal ID (for use with sendTerminalInput, closeTerminal)
	*/
	terminalId: number;
	/**
	* The split ID (if created in a new split)
	*/
	splitId: number | null;
};
type CreateTerminalOptions = {
	/**
	* Working directory for the terminal (defaults to editor cwd)
	*/
	cwd?: string;
	/**
	* Split direction: "horizontal" or "vertical" (default: "vertical")
	*/
	direction?: string;
	/**
	* Split ratio 0.0-1.0 (default: 0.5)
	*/
	ratio?: number;
	/**
	* Whether to focus the new terminal split (default: true)
	*/
	focus?: boolean;
	/**
	* Whether this terminal is part of the user's persisted workspace.
	* Defaults to `false` for plugin-created terminals — they are typically
	* one-off tool UIs (rebuilds, exec shells, build output) and should
	* start with empty scrollback on each invocation. Set to `true` only
	* when the plugin owns a terminal that the user should see restored
	* across editor restarts.
	*/
	persistent?: boolean;
};
type CursorInfo = {
	/**
	* Byte position of the cursor
	*/
	position: number;
	/**
	* Selection range (if any)
	*/
	selection: {
		start: number;
		end: number;
	} | null;
};
type OverlayOptions = {
	/**
	* Foreground color - RGB array or theme key string
	*/
	fg?: OverlayColorSpec | null;
	/**
	* Background color - RGB array or theme key string
	*/
	bg?: OverlayColorSpec | null;
	/**
	* Whether to render with underline
	*/
	underline: boolean;
	/**
	* Whether to render in bold
	*/
	bold: boolean;
	/**
	* Whether to render in italic
	*/
	italic: boolean;
	/**
	* Whether to render with strikethrough
	*/
	strikethrough: boolean;
	/**
	* Whether to extend background color to end of line
	*/
	extendToLineEnd: boolean;
	/**
	* Optional URL for OSC 8 terminal hyperlinks.
	* When set, the overlay text becomes a clickable hyperlink in terminals
	* that support OSC 8 escape sequences.
	*/
	url?: string | null;
};
type OverlayColorSpec = [number, number, number] | string;
type InlineOverlay = {
	/**
	* Start byte offset within the entry's text
	*/
	start: number;
	/**
	* End byte offset within the entry's text (exclusive)
	*/
	end: number;
	/**
	* Styling options for this range
	*/
	style: Partial<OverlayOptions>;
	/**
	* Optional properties for this sub-range (e.g., click target metadata)
	*/
	properties?: Record<string, any>;
};
type GrammarInfoSnapshot = {
	/**
	* The grammar name as used in config files (case-insensitive matching)
	*/
	name: string;
	/**
	* Where this grammar was loaded from (e.g. "built-in", "plugin (myplugin)")
	*/
	source: string;
	/**
	* File extensions associated with this grammar
	*/
	file_extensions: Array<string>;
	/**
	* Optional short name alias (e.g., "bash" for "Bourne Again Shell (bash)")
	*/
	short_name: string | null;
};
type AuthorityFilesystem = {
	kind: "local";
};
type AuthoritySpawner = {
	kind: "local";
} | {
	kind: "docker-exec";
	container_id: string;
	user?: string | null;
	workspace?: string | null;
};
type AuthorityTerminalWrapper = {
	kind: "host-shell";
} | {
	kind: "explicit";
	command: string;
	args: string[];
	manages_cwd?: boolean;
};
type AuthorityPayload = {
	filesystem: AuthorityFilesystem;
	spawner: AuthoritySpawner;
	terminal_wrapper: AuthorityTerminalWrapper;
	display_label?: string;
};
type BackgroundProcessResult = {
	/**
	* Unique process ID for later reference
	*/
	process_id: number;
	/**
	* Process exit code (0 usually means success, -1 if killed)
	* Only present when the process has exited
	*/
	exit_code: number;
};
type BufferSavedDiff = {
	equal: boolean;
	byte_ranges: Array<[number, number]>;
};
type CreateVirtualBufferInExistingSplitOptions = {
	/**
	* Buffer name (displayed in tabs/title)
	*/
	name: string;
	/**
	* Target split ID (required)
	*/
	splitId: number;
	/**
	* Mode for keybindings (e.g., "git-log", "search-results")
	*/
	mode?: string;
	/**
	* Whether buffer is read-only (default: false)
	*/
	readOnly?: boolean;
	/**
	* Show line numbers in gutter (default: true)
	*/
	showLineNumbers?: boolean;
	/**
	* Show cursor (default: true)
	*/
	showCursors?: boolean;
	/**
	* Disable text editing (default: false)
	*/
	editingDisabled?: boolean;
	/**
	* Enable line wrapping
	*/
	lineWrap?: boolean;
	/**
	* Initial content entries with optional properties
	*/
	entries?: Array<TextPropertyEntry>;
};
type CreateVirtualBufferInSplitOptions = {
	/**
	* Buffer name (displayed in tabs/title)
	*/
	name: string;
	/**
	* Mode for keybindings (e.g., "git-log", "search-results")
	*/
	mode?: string;
	/**
	* Whether buffer is read-only (default: false)
	*/
	readOnly?: boolean;
	/**
	* Split ratio 0.0-1.0 (default: 0.5)
	*/
	ratio?: number;
	/**
	* Split direction: "horizontal" or "vertical"
	*/
	direction?: string;
	/**
	* Panel ID to split from
	*/
	panelId?: string;
	/**
	* Show line numbers in gutter (default: true)
	*/
	showLineNumbers?: boolean;
	/**
	* Show cursor (default: true)
	*/
	showCursors?: boolean;
	/**
	* Disable text editing (default: false)
	*/
	editingDisabled?: boolean;
	/**
	* Enable line wrapping
	*/
	lineWrap?: boolean;
	/**
	* Place the new buffer before (left/top of) the existing content (default: false)
	*/
	before?: boolean;
	/**
	* Initial content entries with optional properties
	*/
	entries?: Array<TextPropertyEntry>;
};
type CreateVirtualBufferOptions = {
	/**
	* Buffer name (displayed in tabs/title)
	*/
	name: string;
	/**
	* Mode for keybindings (e.g., "git-log", "search-results")
	*/
	mode?: string;
	/**
	* Whether buffer is read-only (default: false)
	*/
	readOnly?: boolean;
	/**
	* Show line numbers in gutter (default: false)
	*/
	showLineNumbers?: boolean;
	/**
	* Show cursor (default: true)
	*/
	showCursors?: boolean;
	/**
	* Disable text editing (default: false)
	*/
	editingDisabled?: boolean;
	/**
	* Hide from tab bar (default: false)
	*/
	hiddenFromTabs?: boolean;
	/**
	* Initial content entries with optional properties
	*/
	entries?: Array<TextPropertyEntry>;
};
type GrepMatch = {
	/**
	* Absolute file path
	*/
	file: string;
	/**
	* Buffer ID if the file is open (0 if not)
	*/
	bufferId: number;
	/**
	* Byte offset of match start in the file/buffer content
	*/
	byteOffset: number;
	/**
	* Match length in bytes
	*/
	length: number;
	/**
	* 1-indexed line number
	*/
	line: number;
	/**
	* 1-indexed column number
	*/
	column: number;
	/**
	* The matched line content (for display)
	*/
	context: string;
};
type LanguagePackConfig = {
	/**
	* Comment prefix for line comments (e.g., "//" or "#")
	*/
	commentPrefix: string | null;
	/**
	* Block comment start marker (e.g., slash-star)
	*/
	blockCommentStart: string | null;
	/**
	* Block comment end marker (e.g., star-slash)
	*/
	blockCommentEnd: string | null;
	/**
	* Whether to use tabs instead of spaces for indentation
	*/
	useTabs: boolean | null;
	/**
	* Tab size (number of spaces per tab level)
	*/
	tabSize: number | null;
	/**
	* Whether auto-indent is enabled
	*/
	autoIndent: boolean | null;
	/**
	* Whether to show whitespace tab indicators (→) for this language
	* Defaults to true. Set to false for languages like Go/Hare that use tabs for indentation.
	*/
	showWhitespaceTabs: boolean | null;
	/**
	* Formatter configuration
	*/
	formatter: FormatterPackConfig | null;
};
type LspServerPackConfig = {
	/**
	* Command to start the LSP server
	*/
	command: string;
	/**
	* Arguments to pass to the command
	*/
	args: Array<string>;
	/**
	* Whether to auto-start the server when a matching file is opened
	*/
	autoStart: boolean | null;
	/**
	* LSP initialization options
	*/
	initializationOptions: Record<string, unknown> | null;
	/**
	* Process resource limits (memory and CPU)
	*/
	processLimits: ProcessLimitsPackConfig | null;
};
type RemoteIndicatorStatePayload = {
	kind: "local";
} | {
	kind: "connecting";
	label?: string | null;
} | {
	kind: "connected";
	label?: string | null;
} | {
	kind: "failed_attach";
	error?: string | null;
} | {
	kind: "disconnected";
	label?: string | null;
};
type ReplaceResult = {
	/**
	* Number of replacements made
	*/
	replacements: number;
	/**
	* Buffer ID of the edited buffer
	*/
	bufferId: number;
};
type SpawnResult = {
	/**
	* Complete stdout as string
	*/
	stdout: string;
	/**
	* Complete stderr as string
	*/
	stderr: string;
	/**
	* Process exit code (0 usually means success, -1 if killed)
	*/
	exit_code: number;
};
type TextPropertiesAtCursor = Array<Record<string, unknown>>;
type TsHighlightSpan = {
	start: number;
	end: number;
	color: [number, number, number];
	bold: boolean;
	italic: boolean;
};
type VirtualBufferResult = {
	/**
	* The created buffer ID
	*/
	bufferId: number;
	/**
	* The split ID (if created in a new split)
	*/
	splitId: number | null;
};
/**
* Main editor API interface
*/
interface EditorAPI {
	/**
	* Get the plugin API version. Plugins can check this to verify
	* the editor supports the features they need.
	*/
	apiVersion(): number;
	/**
	* The name of the plugin this `editor` handle belongs to. Used by the
	* M3 plugin-API plane (`exportPluginApi` tags the exporter). Plugin
	* authors generally don't call this directly.
	*/
	pluginName(): string;
	/**
	* Publish a typed API surface under `name`. Another plugin (typically
	* `init.ts`) can reach it later via `getPluginApi(name)`. Calling
	* again with the same `name` replaces the previous registration
	* (idempotent — reload works). Exports are auto-dropped when the
	* calling plugin is unloaded.
	* 
	* Returns `true` on success. Rejects with a TypeError if `name` is
	* empty or `api` is not an object (functions and primitives are not
	* valid API surfaces — only objects).
	*/
	exportPluginApi(name: string, api: unknown): boolean;
	/**
	* Look up a plugin API previously published via `exportPluginApi`.
	* Returns the api object (restored into the caller's context) or
	* `null` if no plugin exports under that name.
	*/
	getPluginApi(name: string): unknown | null;
	/**
	* Get the active buffer ID (0 if none)
	*/
	getActiveBufferId(): number;
	/**
	* Get the active split ID
	*/
	getActiveSplitId(): number;
	/**
	* List all open buffers - returns array of BufferInfo objects
	*/
	listBuffers(): BufferInfo[];
	/**
	* List all available grammars with source info - returns array of GrammarInfo objects
	*/
	listGrammars(): GrammarInfoSnapshot[];
	debug(msg: string): void;
	info(msg: string): void;
	warn(msg: string): void;
	error(msg: string): void;
	setStatus(msg: string): void;
	copyToClipboard(text: string): void;
	setClipboard(text: string): void;
	/**
	* Get the display label for a keybinding by action name and optional mode.
	* Returns null if no binding is found.
	*/
	getKeybindingLabel(action: string, mode: string | null): string | null;
	/**
	* Register a command in the command palette (Ctrl+P).
	* 
	* Usually you should omit `context` so the command is always visible.
	* If provided, the command is **hidden** unless your plugin has activated
	* that context with `editor.setContext(name, true)` or the focused buffer's
	* virtual mode (from `defineMode()`) matches. This is for plugin-defined
	* contexts only (e.g. `"tour-active"`, `"review-mode"`), not built-in
	* editor modes.
	*/
	registerCommand(name: string, description: string, handlerName: string, context?: string | null): boolean;
	/**
	* Unregister a command by name
	*/
	unregisterCommand(name: string): boolean;
	/**
	* Set a context (for keybinding conditions)
	*/
	setContext(name: string, active: boolean): boolean;
	/**
	* Execute a built-in action
	*/
	executeAction(actionName: string): boolean;
	/**
	* Translate a string - reads plugin name from __pluginName__ global
	* Args is optional - can be omitted, undefined, null, or an object
	*/
	t(key: string, ...args: unknown[]): string;
	/**
	* Get cursor position in active buffer
	*/
	getCursorPosition(): number;
	/**
	* Get file path for a buffer
	*/
	getBufferPath(bufferId: number): string;
	/**
	* Get buffer length in bytes
	*/
	getBufferLength(bufferId: number): number;
	/**
	* Check if buffer has unsaved changes
	*/
	isBufferModified(bufferId: number): boolean;
	/**
	* Save a buffer to a specific file path
	* Used by :w filename to save unnamed buffers or save-as
	*/
	saveBufferToPath(bufferId: number, path: string): boolean;
	/**
	* Get buffer info by ID
	*/
	getBufferInfo(bufferId: number): BufferInfo | null;
	/**
	* Get primary cursor info for active buffer
	*/
	getPrimaryCursor(): CursorInfo | null;
	/**
	* Get all cursors for active buffer
	*/
	getAllCursors(): CursorInfo[];
	/**
	* Get all cursor positions as byte offsets
	*/
	getAllCursorPositions(): number[];
	/**
	* Get viewport info for active buffer
	*/
	getViewport(): ViewportInfo | null;
	/**
	* Get the line number (0-indexed) of the primary cursor
	*/
	getCursorLine(): number;
	/**
	* Get the byte offset of the start of a line (0-indexed line number)
	* Returns null if the line number is out of range
	*/
	getLineStartPosition(line: number): Promise<number | null>;
	/**
	* Get the byte offset of the end of a line (0-indexed line number)
	* Returns the position after the last character of the line (before newline)
	* Returns null if the line number is out of range
	*/
	getLineEndPosition(line: number): Promise<number | null>;
	/**
	* Get the total number of lines in the active buffer
	* Returns null if buffer not found
	*/
	getBufferLineCount(): Promise<number | null>;
	/**
	* Scroll a split to center a specific line in the viewport
	* Line is 0-indexed (0 = first line)
	*/
	scrollToLineCenter(splitId: number, bufferId: number, line: number): boolean;
	/**
	* Scroll any split/panel showing `buffer_id` so `line` is visible.
	* Unlike `scrollToLineCenter`, this does not require a split id — it
	* updates every split's viewport whose active buffer is the given
	* buffer, including inner leaves of a buffer group. Use this from
	* a panel plugin to keep the user's "selected" row in view after
	* arrow-key navigation (the plugin's own selection state isn't
	* automatically reflected in the buffer cursor, so the core-driven
	* viewport would otherwise stay put).
	*/
	scrollBufferToLine(bufferId: number, line: number): boolean;
	/**
	* Find buffer by file path, returns buffer ID or 0 if not found
	*/
	findBufferByPath(path: string): number;
	/**
	* Get diff between buffer content and last saved version
	*/
	getBufferSavedDiff(bufferId: number): BufferSavedDiff | null;
	/**
	* Insert text at a position in a buffer
	*/
	insertText(bufferId: number, position: number, text: string): boolean;
	/**
	* Delete a range from a buffer
	*/
	deleteRange(bufferId: number, start: number, end: number): boolean;
	/**
	* Insert text at cursor position in active buffer
	*/
	insertAtCursor(text: string): boolean;
	/**
	* Open a file, optionally at a specific line/column
	*/
	openFile(path: string, line: number | null, column: number | null): boolean;
	/**
	* Open a file in a specific split
	*/
	openFileInSplit(splitId: number, path: string, line: number, column: number): boolean;
	/**
	* Show a buffer in the current split
	*/
	showBuffer(bufferId: number): boolean;
	/**
	* Close a buffer
	*/
	closeBuffer(bufferId: number): boolean;
	/**
	* Subscribe to an editor event
	*/
	on(eventName: string, handlerName: string): void;
	/**
	* Unsubscribe from an event
	*/
	off(eventName: string, handlerName: string): void;
	/**
	* Get an environment variable
	*/
	getEnv(name: string): string | null;
	/**
	* Get current working directory
	*/
	getCwd(): string;
	/**
	* Get the active authority's display label.
	* 
	* Empty means the local (default) authority. A non-empty value
	* means a plugin-installed or SSH authority is in effect (e.g.
	* `"Container:abc123def456"` for a devcontainer). Intended as a
	* simple "am I already attached?" check that survives editor
	* restarts — the label lives on the `Editor` state snapshot so it
	* is fresh after the authority-transition restart flow.
	*/
	getAuthorityLabel(): string;
	/**
	* Join path components (variadic - accepts multiple string arguments)
	* Always uses forward slashes for cross-platform consistency (like Node.js path.posix.join)
	* 
	* Preserves up to 2 leading slashes, which matters on Windows: Rust's
	* `Path::canonicalize` returns `\\?\`-prefixed paths, and `editor.getCwd()`
	* surfaces that to plugin code verbatim. After the backslash→slash
	* normalization the prefix becomes `//?/C:/...`; collapsing the leading
	* `//` to a single `/` yields `/?/C:/...`, which every filesystem API on
	* Windows rejects, breaking `findConfig()`-style plugin logic.
	*/
	pathJoin(...parts: string[]): string;
	/**
	* Get directory name from path
	*/
	pathDirname(path: string): string;
	/**
	* Get file name from path
	*/
	pathBasename(path: string): string;
	/**
	* Get file extension
	*/
	pathExtname(path: string): string;
	/**
	* Check if path is absolute
	*/
	pathIsAbsolute(path: string): boolean;
	/**
	* Convert a file:// URI to a local file path.
	* Handles percent-decoding and Windows drive letters.
	* Returns an empty string if the URI is not a valid file URI.
	*/
	fileUriToPath(uri: string): string;
	/**
	* Convert a local file path to a file:// URI.
	* Handles Windows drive letters and special characters.
	* Returns an empty string if the path cannot be converted.
	*/
	pathToFileUri(path: string): string;
	/**
	* Get the UTF-8 byte length of a JavaScript string.
	* 
	* JS strings are UTF-16 internally, so `str.length` returns the number of
	* UTF-16 code units, not the number of bytes in a UTF-8 encoding.  The
	* editor API uses byte offsets for all buffer positions (overlays, cursor,
	* getBufferText ranges, etc.).  This helper lets plugins convert JS string
	* lengths / regex match indices to the byte offsets the editor expects.
	*/
	utf8ByteLength(text: string): number;
	/**
	* Check if file exists
	*/
	fileExists(path: string): boolean;
	/**
	* Read file contents
	*/
	readFile(path: string): string | null;
	/**
	* Write file contents
	*/
	writeFile(path: string, content: string): boolean;
	/**
	* Read directory contents (returns array of {name, is_file, is_dir})
	*/
	readDir(path: string): DirEntry[];
	/**
	* Create a directory (and all parent directories) recursively.
	* Returns true if the directory was created or already exists.
	*/
	createDir(path: string): boolean;
	/**
	* Remove a file or directory by moving it to the OS trash/recycle bin.
	* For safety, the path must be under the OS temp directory or the Fresh
	* config directory. Returns true on success.
	*/
	removePath(path: string): boolean;
	/**
	* Rename/move a file or directory. Returns true on success.
	* Falls back to copy then trash for cross-filesystem moves.
	*/
	renamePath(from: string, to: string): boolean;
	/**
	* Copy a file or directory recursively to a new location.
	* Returns true on success.
	*/
	copyPath(from: string, to: string): boolean;
	/**
	* Get the OS temporary directory path.
	*/
	getTempDir(): string;
	/**
	* Parse a JSONC (JSON with comments) string into a JS value.
	* 
	* Accepts the JSONC superset: line and block comments, trailing
	* commas, single-quoted strings, and unquoted object keys — matching
	* devcontainer.json / tsconfig.json / VS Code settings.json.
	* 
	* Throws a JS error (catchable with try/catch) when the input is not
	* valid JSONC, like `JSON.parse` does for invalid JSON.
	*/
	parseJsonc(text: string): unknown;
	/**
	* Get current config as JS object.
	* 
	* The snapshot holds an `Arc<serde_json::Value>` that was serialized
	* on the editor side the last time the underlying `Arc<Config>`
	* changed. Cloning the Arc inside the read lock is a refcount bump;
	* the actual walk into the JS runtime happens outside the lock.
	*/
	getConfig(): unknown;
	/**
	* Get user config as JS object. Same Arc-clone pattern as `get_config`.
	*/
	getUserConfig(): unknown;
	/**
	* Reload configuration from file
	*/
	reloadConfig(): void;
	/**
	* Set a single config setting in the runtime layer for this session.
	* 
	* `path` is dot-separated (e.g. `"editor.tab_size"`). `value` is any JSON
	* value in the shape the setting expects. The write lives in an
	* in-memory layer scoped to the calling plugin — it does not modify
	* `config.json`, and unloading the plugin (or reloading init.ts) drops
	* it. Intended use is `init.ts` running a conditional:
	* `if (editor.getEnv("SSH_TTY")) editor.setSetting("terminal.mouse", false);`
	* 
	* Returns `true` if the write was queued. The actual update is
	* asynchronous; a subsequent `getConfig()` will reflect it after the
	* editor processes the command.
	*/
	setSetting(path: string, value: unknown): boolean;
	/**
	* Reload theme registry from disk
	* Call this after installing theme packages or saving new themes
	*/
	reloadThemes(): void;
	/**
	* Reload theme registry and apply a theme atomically
	*/
	reloadAndApplyTheme(themeName: string): void;
	/**
	* Register a TextMate grammar file for a language
	* The grammar will be pending until reload_grammars() is called
	*/
	registerGrammar(language: string, grammarPath: string, extensions: string[]): boolean;
	/**
	* Register language configuration (comment prefix, indentation, formatter)
	*/
	registerLanguageConfig(language: string, config: LanguagePackConfig): boolean;
	/**
	* Register an LSP server for a language
	*/
	registerLspServer(language: string, config: LspServerPackConfig): boolean;
	/**
	* Reload the grammar registry to apply registered grammars (async)
	* Call this after registering one or more grammars.
	* Returns a Promise that resolves when the grammar rebuild completes.
	*/
	reloadGrammars(): Promise<void>;
	/**
	* Get the directory where this plugin's files are stored.
	* For package plugins this is `<plugins_dir>/packages/<plugin_name>/`.
	*/
	getPluginDir(): string;
	/**
	* Get config directory path
	*/
	getConfigDir(): string;
	/**
	* Get the persistent data directory path (DirectoryContext::data_dir).
	* Intended for plugin state that should outlive a single session — e.g.
	* review-diff comments keyed off git state.
	*/
	getDataDir(): string;
	/**
	* Get themes directory path
	*/
	getThemesDir(): string;
	/**
	* Apply a theme by name
	*/
	applyTheme(themeName: string): boolean;
	/**
	* Override theme colors in-memory for the running session. `overrides`
	* is a JS object mapping `"section.field"` keys (same namespace as
	* `getThemeSchema`) to `[r, g, b]` triplets (0–255 each).
	* 
	* Unknown keys are dropped silently; out-of-range values are clamped
	* to `0..=255`. Overrides survive until the next `applyTheme` call
	* (which replaces the whole `Theme`). Intended for fast animation
	* loops from `init.ts` — no disk I/O, no theme-registry rescan.
	*/
	overrideThemeColors(overrides: unknown): boolean;
	/**
	* Get theme schema as JS object
	*/
	getThemeSchema(): unknown;
	/**
	* Get list of builtin themes as JS object
	*/
	getBuiltinThemes(): unknown;
	/**
	* Delete a custom theme (alias for deleteThemeSync)
	*/
	deleteTheme(name: string): boolean;
	/**
	* Get theme data (JSON) by name from the in-memory cache
	*/
	getThemeData(name: string): unknown;
	/**
	* Save a theme file to the user themes directory, returns the saved path
	*/
	saveThemeFile(name: string, content: string): string;
	/**
	* Check if a user theme file exists
	*/
	themeFileExists(name: string): boolean;
	/**
	* Get file stat information
	*/
	fileStat(path: string): unknown;
	/**
	* Check if a background process is still running
	*/
	isProcessRunning(processId: number): boolean;
	/**
	* Kill a process by ID (alias for killBackgroundProcess)
	*/
	killProcess(processId: number): boolean;
	/**
	* Translate a key for a specific plugin
	*/
	pluginTranslate(pluginName: string, key: string, args?: Record<string, unknown>): string;
	/**
	* Create a composite buffer (async)
	* 
	* Uses typed CreateCompositeBufferOptions - serde validates field names at runtime
	* via `deny_unknown_fields` attribute
	*/
	createCompositeBuffer(opts: TsCreateCompositeBufferOptions): Promise<number>;
	/**
	* Update alignment hunks for a composite buffer
	* 
	* Uses typed Vec<CompositeHunk> - serde validates field names at runtime
	*/
	updateCompositeAlignment(bufferId: number, hunks: TsCompositeHunk[]): boolean;
	/**
	* Close a composite buffer
	*/
	closeCompositeBuffer(bufferId: number): boolean;
	/**
	* Force-materialize render-dependent state (like `layoutIfNeeded` in UIKit).
	* After calling this, commands that depend on view state created during
	* rendering (e.g., `compositeNextHunk`) will work correctly.
	*/
	flushLayout(): boolean;
	/**
	* Navigate to the next hunk in a composite buffer
	*/
	compositeNextHunk(bufferId: number): boolean;
	/**
	* Navigate to the previous hunk in a composite buffer
	*/
	compositePrevHunk(bufferId: number): boolean;
	/**
	* Request syntax highlights for a buffer range (async)
	*/
	getHighlights(bufferId: number, start: number, end: number): Promise<TsHighlightSpan[]>;
	/**
	* Add an overlay with styling options
	* 
	* Colors can be specified as RGB arrays `[r, g, b]` or theme key strings.
	* Theme keys are resolved at render time, so overlays update with theme changes.
	* 
	* Theme key examples: "ui.status_bar_fg", "editor.selection_bg", "syntax.keyword"
	* 
	* Options: fg, bg (RGB array or theme key string), bold, italic, underline,
	* strikethrough, extend_to_line_end (all booleans, default false).
	* 
	* Example usage in TypeScript:
	* ```typescript
	* editor.addOverlay(bufferId, "my-namespace", 0, 10, {
	* fg: "syntax.keyword",           // theme key
	* bg: [40, 40, 50],               // RGB array
	* bold: true,
	* strikethrough: true,
	* });
	* ```
	*/
	addOverlay(bufferId: number, namespace: string, start: number, end: number, options: Record<string, unknown>): boolean;
	/**
	* Clear all overlays in a namespace
	*/
	clearNamespace(bufferId: number, namespace: string): boolean;
	/**
	* Clear all overlays from a buffer
	*/
	clearAllOverlays(bufferId: number): boolean;
	/**
	* Clear all overlays that overlap with a byte range
	*/
	clearOverlaysInRange(bufferId: number, start: number, end: number): boolean;
	/**
	* Remove an overlay by its handle
	*/
	removeOverlay(bufferId: number, handle: string): boolean;
	/**
	* Add a conceal range that hides or replaces a byte range during rendering
	*/
	addConceal(bufferId: number, namespace: string, start: number, end: number, replacement: string | null): boolean;
	/**
	* Clear all conceal ranges in a namespace
	*/
	clearConcealNamespace(bufferId: number, namespace: string): boolean;
	/**
	* Clear all conceal ranges that overlap with a byte range
	*/
	clearConcealsInRange(bufferId: number, start: number, end: number): boolean;
	/**
	* Add a collapsed fold range. Hides bytes [start, end) from
	* rendering — the line containing `start - 1` (the fold "header")
	* stays visible, while subsequent lines covered by the range are
	* skipped.
	*/
	addFold(bufferId: number, start: number, end: number, placeholder?: string): boolean;
	/**
	* Clear every collapsed fold range on the buffer.
	*/
	clearFolds(bufferId: number): boolean;
	/**
	* Add a soft break point for marker-based line wrapping
	*/
	addSoftBreak(bufferId: number, namespace: string, position: number, indent: number): boolean;
	/**
	* Clear all soft breaks in a namespace
	*/
	clearSoftBreakNamespace(bufferId: number, namespace: string): boolean;
	/**
	* Clear all soft breaks that fall within a byte range
	*/
	clearSoftBreaksInRange(bufferId: number, start: number, end: number): boolean;
	/**
	* Submit a view transform for a buffer/split
	* 
	* Accepts tokens in the simple format:
	* {kind: "text"|"newline"|"space"|"break", text: "...", sourceOffset: N, style?: {...}}
	* 
	* Also accepts the TypeScript-defined format for backwards compatibility:
	* {kind: {Text: "..."} | "Newline" | "Space" | "Break", source_offset: N, style?: {...}}
	*/
	submitViewTransform(bufferId: number, splitId: number | null, start: number, end: number, tokens: Record<string, unknown>[], layoutHints?: Record<string, unknown>): boolean;
	/**
	* Clear view transform for a buffer/split
	*/
	clearViewTransform(bufferId: number, splitId: number | null): boolean;
	/**
	* Set layout hints (compose width, column guides) for a buffer/split
	* without going through the view_transform pipeline.
	*/
	setLayoutHints(bufferId: number, splitId: number | null, hints: LayoutHints): boolean;
	/**
	* Set file explorer decorations for a namespace
	*/
	setFileExplorerDecorations(namespace: string, decorations: Record<string, unknown>[]): boolean;
	/**
	* Clear file explorer decorations for a namespace
	*/
	clearFileExplorerDecorations(namespace: string): boolean;
	/**
	* Add virtual text (inline text that doesn't exist in the buffer)
	*/
	addVirtualText(bufferId: number, virtualTextId: string, position: number, text: string, r: number, g: number, b: number, before: boolean, useBg: boolean): boolean;
	/**
	* Remove a virtual text by ID
	*/
	removeVirtualText(bufferId: number, virtualTextId: string): boolean;
	/**
	* Remove virtual texts whose ID starts with the given prefix
	*/
	removeVirtualTextsByPrefix(bufferId: number, prefix: string): boolean;
	/**
	* Clear all virtual texts from a buffer
	*/
	clearVirtualTexts(bufferId: number): boolean;
	/**
	* Clear all virtual texts in a namespace
	*/
	clearVirtualTextNamespace(bufferId: number, namespace: string): boolean;
	/**
	* Add a virtual line (full line above/below a position)
	* 
	* The `options` object accepts:
	* * `fg`, `bg` — either an `[r, g, b]` array (each `0..=255`) or a
	* theme-key string (e.g. `"editor.line_number_fg"`).  Theme keys
	* are resolved at render time so the line follows theme changes.
	* Both default to `null` (no foreground / transparent background).
	*/
	addVirtualLine(bufferId: number, position: number, text: string, options: Record<string, unknown>, above: boolean, namespace: string, priority: number): boolean;
	/**
	* Show a prompt and wait for user input (async)
	* Returns the user input or null if cancelled
	*/
	prompt(label: string, initialValue: string): Promise<string | null>;
	/**
	* Start an interactive prompt
	*/
	startPrompt(label: string, promptType: string): boolean;
	/**
	* Start a prompt with initial value
	*/
	startPromptWithInitial(label: string, promptType: string, initialValue: string): boolean;
	/**
	* Set suggestions for the current prompt
	* 
	* Uses typed Vec<Suggestion> - serde validates field names at runtime
	*/
	setPromptSuggestions(suggestions: PromptSuggestion[]): boolean;
	setPromptInputSync(sync: boolean): boolean;
	/**
	* Define a buffer mode (takes bindings as array of [key, command] pairs)
	*/
	defineMode(name: string, bindingsArr: string[][], readOnly?: boolean, allowTextInput?: boolean, inheritNormalBindings?: boolean): boolean;
	/**
	* Set the global editor mode
	*/
	setEditorMode(mode: string | null): boolean;
	/**
	* Get the current editor mode
	*/
	getEditorMode(): string | null;
	/**
	* Close a split
	*/
	closeSplit(splitId: number): boolean;
	/**
	* Set the buffer displayed in a split
	*/
	setSplitBuffer(splitId: number, bufferId: number): boolean;
	/**
	* Focus a specific split
	*/
	focusSplit(splitId: number): boolean;
	/**
	* Set scroll position of a split
	*/
	setSplitScroll(splitId: number, topByte: number): boolean;
	/**
	* Set the ratio of a split (0.0 to 1.0, 0.5 = equal)
	*/
	setSplitRatio(splitId: number, ratio: number): boolean;
	/**
	* Set a label on a split (e.g., "sidebar")
	*/
	setSplitLabel(splitId: number, label: string): boolean;
	/**
	* Remove a label from a split
	*/
	clearSplitLabel(splitId: number): boolean;
	/**
	* Find a split by label (async)
	*/
	getSplitByLabel(label: string): Promise<number | null>;
	/**
	* Distribute all splits evenly
	*/
	distributeSplitsEvenly(): boolean;
	/**
	* Set cursor position in a buffer
	*/
	setBufferCursor(bufferId: number, position: number): boolean;
	/**
	* Toggle whether the editor draws a native caret in this buffer.
	* 
	* Buffer-group panel buffers default to `show_cursors = false`, which
	* also blocks all native movement actions in `action_to_events`. Plugins
	* that want native cursor motion in a panel (e.g. magit-style row
	* navigation) call this with `true` after `createBufferGroup` returns.
	*/
	setBufferShowCursors(bufferId: number, show: boolean): boolean;
	/**
	* Set a line indicator in the gutter
	*/
	setLineIndicator(bufferId: number, line: number, namespace: string, symbol: string, r: number, g: number, b: number, priority: number): boolean;
	/**
	* Batch set line indicators in the gutter
	*/
	setLineIndicators(bufferId: number, lines: number[], namespace: string, symbol: string, r: number, g: number, b: number, priority: number): boolean;
	/**
	* Clear line indicators in a namespace
	*/
	clearLineIndicators(bufferId: number, namespace: string): boolean;
	/**
	* Enable or disable line numbers for a buffer
	*/
	setLineNumbers(bufferId: number, enabled: boolean): boolean;
	/**
	* Set the view mode for a buffer ("source" or "compose")
	*/
	setViewMode(bufferId: number, mode: string): boolean;
	/**
	* Enable or disable line wrapping for a buffer/split
	*/
	setLineWrap(bufferId: number, splitId: number | null, enabled: boolean): boolean;
	/**
	* Set plugin-managed per-buffer view state (write-through to snapshot + command for persistence)
	*/
	setViewState(bufferId: number, key: string, value: unknown): boolean;
	/**
	* Get plugin-managed per-buffer view state (reads from snapshot)
	*/
	getViewState(bufferId: number, key: string): unknown;
	/**
	* Set plugin-managed global state (write-through to snapshot + command for persistence).
	* State is automatically isolated per plugin using the plugin's name.
	* TODO: Need to think about plugin isolation / namespacing strategy for these APIs.
	*/
	setGlobalState(key: string, value: unknown): boolean;
	/**
	* Get plugin-managed global state (reads from snapshot).
	* State is automatically isolated per plugin using the plugin's name.
	* TODO: Need to think about plugin isolation / namespacing strategy for these APIs.
	*/
	getGlobalState(key: string): unknown;
	/**
	* Create a scroll sync group for anchor-based synchronized scrolling
	*/
	createScrollSyncGroup(groupId: number, leftSplit: number, rightSplit: number): boolean;
	/**
	* Set sync anchors for a scroll sync group
	*/
	setScrollSyncAnchors(groupId: number, anchors: number[][]): boolean;
	/**
	* Remove a scroll sync group
	*/
	removeScrollSyncGroup(groupId: number): boolean;
	/**
	* Execute multiple actions in sequence
	* 
	* Takes typed ActionSpec array - serde validates field names at runtime
	*/
	executeActions(actions: ActionSpec[]): boolean;
	/**
	* Show an action popup
	* 
	* Takes a typed ActionPopupOptions struct - serde validates field names at runtime
	*/
	showActionPopup(opts: ActionPopupOptions): boolean;
	/**
	* Disable LSP for a specific language
	*/
	disableLspForLanguage(language: string): boolean;
	/**
	* Restart LSP server for a specific language
	*/
	restartLspForLanguage(language: string): boolean;
	/**
	* Set the workspace root URI for a specific language's LSP server
	* This allows plugins to specify project roots (e.g., directory containing .csproj)
	*/
	setLspRootUri(language: string, uri: string): boolean;
	/**
	* Get all diagnostics from LSP
	*/
	getAllDiagnostics(): JsDiagnostic[];
	/**
	* Get registered event handlers for an event
	*/
	getHandlers(eventName: string): string[];
	/**
	* Create a virtual buffer in current split (async, returns buffer and split IDs)
	*/
	createVirtualBuffer(opts: CreateVirtualBufferOptions): Promise<VirtualBufferResult>;
	/**
	* Create a virtual buffer in a new split (async, returns buffer and split IDs)
	*/
	createVirtualBufferInSplit(opts: CreateVirtualBufferInSplitOptions): Promise<VirtualBufferResult>;
	/**
	* Create a virtual buffer in an existing split (async, returns buffer and split IDs)
	*/
	createVirtualBufferInExistingSplit(opts: CreateVirtualBufferInExistingSplitOptions): Promise<VirtualBufferResult>;
	/**
	* Set the content of a panel within a buffer group
	*/
	setPanelContent(groupId: number, panelName: string, entriesArr: Record<string, unknown>[]): boolean;
	/**
	* Close a buffer group
	*/
	closeBufferGroup(groupId: number): boolean;
	/**
	* Focus a specific panel within a buffer group
	*/
	focusBufferGroupPanel(groupId: number, panelName: string): boolean;
	/**
	* Set virtual buffer content (takes array of entry objects)
	* 
	* Note: entries should be TextPropertyEntry[] - uses manual parsing for HashMap support
	*/
	setVirtualBufferContent(bufferId: number, entriesArr: Record<string, unknown>[]): boolean;
	/**
	* Get text properties at cursor position (returns JS array)
	*/
	getTextPropertiesAtCursor(bufferId: number): TextPropertiesAtCursor;
	/**
	* Spawn a process (async, returns request_id)
	*/
	spawnProcess(command: string, args: string[], cwd?: string): ProcessHandle<SpawnResult>;
	/**
	* Spawn a process on the host regardless of the active authority.
	* 
	* Intended for plugin internals that must run host-side work
	* (e.g. `devcontainer up`) before installing an authority that
	* would otherwise route the spawn elsewhere. Same calling shape
	* as `spawnProcess`.
	*/
	spawnHostProcess(command: string, args: string[], cwd?: string): ProcessHandle<SpawnResult>;
	/**
	* Install a new authority via an opaque payload.
	* 
	* The payload is a JS object describing filesystem + spawner +
	* terminal wrapper + display label. The canonical schema lives in
	* the `AuthorityPayload` type in `fresh-editor`; plugins should
	* hand-build objects that match it. Fire-and-forget: the editor
	* restarts as part of the transition, so the plugin is reloaded
	* before any follow-up work can run on this call's return value.
	*/
	setAuthority(payload: AuthorityPayload): boolean;
	/**
	* Restore the default local authority. Same restart semantics as
	* `setAuthority`.
	*/
	clearAuthority(): void;
	/**
	* Override the Remote Indicator's displayed state. Plugins call
	* this to surface lifecycle transitions that the authority layer
	* doesn't know about yet — "Connecting" while `devcontainer up`
	* runs, "FailedAttach" after a non-zero exit, etc.
	* 
	* Accepts a tagged JS object:
	* ```ts
	* editor.setRemoteIndicatorState({ kind: "connecting", label: "Building" });
	* editor.setRemoteIndicatorState({ kind: "failed_attach", error: "exit 1" });
	* editor.setRemoteIndicatorState({ kind: "connected", label: "Container:abc" });
	* editor.setRemoteIndicatorState({ kind: "local" });
	* ```
	* 
	* The override sticks until replaced or cleared via
	* `clearRemoteIndicatorState`. Editor restart (e.g. on
	* `setAuthority`) resets it — plugins must reassert after a
	* post-restart init if they want the override to persist.
	*/
	setRemoteIndicatorState(state: RemoteIndicatorStatePayload): boolean;
	/**
	* Drop any active Remote Indicator override. Safe to call even
	* without a prior `setRemoteIndicatorState`.
	*/
	clearRemoteIndicatorState(): void;
	/**
	* Wait for a process to complete and get its result (async)
	*/
	spawnProcessWait(processId: number): Promise<SpawnResult>;
	/**
	* Get buffer text range (async, returns request_id)
	*/
	getBufferText(bufferId: number, start: number, end: number): Promise<string>;
	/**
	* Delay/sleep (async, returns request_id)
	*/
	delay(durationMs: number): Promise<void>;
	/**
	* Project-wide grep search (async)
	* Searches all files in the project, respecting .gitignore.
	* Open buffers with dirty edits are searched in-memory.
	*/
	grepProject(pattern: string, fixedString: boolean | null, caseSensitive: boolean | null, maxResults: number | null, wholeWords: boolean | null): Promise<GrepMatch[]>;
	/**
	* Streaming project-wide grep search
	* Returns a thenable with a searchId property. The progressCallback is called
	* with batches of matches as they are found.
	*/
	grepProjectStreaming(pattern: string, opts?: {
		fixedString?: boolean;
		caseSensitive?: boolean;
		maxResults?: number;
		wholeWords?: boolean;
	}, progressCallback?: (matches: GrepMatch[], done: boolean) => void): PromiseLike<GrepMatch[]> & {
		searchId: number;
	};
	/**
	* Replace matches in a file's buffer (async)
	* Opens the file if not already in a buffer, applies edits via the buffer model,
	* and saves. All edits are grouped as a single undo action.
	*/
	replaceInFile(filePath: string, matches: number[][], replacement: string): Promise<ReplaceResult>;
	/**
	* Send LSP request (async, returns request_id)
	*/
	sendLspRequest(language: string, method: string, params: Record<string, unknown> | null): Promise<unknown>;
	/**
	* Spawn a background process (async, returns request_id which is also process_id)
	*/
	spawnBackgroundProcess(command: string, args: string[], cwd?: string): ProcessHandle<BackgroundProcessResult>;
	/**
	* Kill a background process
	*/
	killBackgroundProcess(processId: number): boolean;
	/**
	* Create a new terminal in a split (async, returns TerminalResult)
	*/
	createTerminal(opts?: CreateTerminalOptions): Promise<TerminalResult>;
	/**
	* Send input data to a terminal
	*/
	sendTerminalInput(terminalId: number, data: string): boolean;
	/**
	* Close a terminal
	*/
	closeTerminal(terminalId: number): boolean;
	/**
	* Force refresh of line display
	*/
	refreshLines(bufferId: number): boolean;
	/**
	* Get the current locale
	*/
	getCurrentLocale(): string;
	/**
	* Load a plugin from a file path (async)
	*/
	loadPlugin(path: string): Promise<boolean>;
	/**
	* Unload a plugin by name (async)
	*/
	unloadPlugin(name: string): Promise<boolean>;
	/**
	* Reload a plugin by name (async)
	*/
	reloadPlugin(name: string): Promise<boolean>;
	/**
	* List all loaded plugins (async)
	* Returns array of { name: string, path: string, enabled: boolean }
	*/
	listPlugins(): Promise<Array<{
		name: string;
		path: string;
		enabled: boolean;
	}>>;
}
/**
* Typed overload of `editor.getPluginApi`. When the caller passes a
* key that some loaded plugin declared in `FreshPluginRegistry`, the
* return type is narrowed to that plugin's API. Unknown names fall
* through to the untyped `unknown | null` signature.
*/
interface EditorAPI {
	getPluginApi<K extends keyof FreshPluginRegistry>(name: K): FreshPluginRegistry[K] | null;
}
