Skip to main content

JSEDITORAPI_TS_EDITOR_API

Constant JSEDITORAPI_TS_EDITOR_API 

Source
pub const JSEDITORAPI_TS_EDITOR_API: &str = "/**\n * Main editor API interface\n */\ninterface EditorAPI {\n  /**\n   * Get the plugin API version. Plugins can check this to verify\n   * the editor supports the features they need.\n   */\n  apiVersion(): number;\n\n  /**\n   * The name of the plugin this `editor` handle belongs to. Used by the\n   * M3 plugin-API plane (`exportPluginApi` tags the exporter). Plugin\n   * authors generally don\'t call this directly.\n   */\n  pluginName(): string;\n\n  /**\n   * Publish a typed API surface under `name`. Another plugin (typically\n   * `init.ts`) can reach it later via `getPluginApi(name)`. Calling\n   * again with the same `name` replaces the previous registration\n   * (idempotent \u{2014} reload works). Exports are auto-dropped when the\n   * calling plugin is unloaded.\n   * \n   * Returns `true` on success. Rejects with a TypeError if `name` is\n   * empty or `api` is not an object (functions and primitives are not\n   * valid API surfaces \u{2014} only objects).\n   */\n  exportPluginApi(name: string, api: unknown): boolean;\n\n  /**\n   * Look up a plugin API previously published via `exportPluginApi`.\n   * Returns the api object (restored into the caller\'s context) or\n   * `null` if no plugin exports under that name.\n   */\n  getPluginApi(name: string): unknown | null;\n\n  /**\n   * Get the active buffer ID (0 if none)\n   */\n  getActiveBufferId(): number;\n\n  /**\n   * Get the active split ID\n   */\n  getActiveSplitId(): number;\n\n  /**\n   * List all open buffers - returns array of BufferInfo objects\n   */\n  listBuffers(): BufferInfo[];\n\n  /**\n   * List all available grammars with source info - returns array of GrammarInfo objects\n   */\n  listGrammars(): GrammarInfoSnapshot[];\n\n  debug(msg: string): void;\n\n  info(msg: string): void;\n\n  warn(msg: string): void;\n\n  error(msg: string): void;\n\n  setStatus(msg: string): void;\n\n  copyToClipboard(text: string): void;\n\n  setClipboard(text: string): void;\n\n  /**\n   * Get the display label for a keybinding by action name and optional mode.\n   * Returns null if no binding is found.\n   */\n  getKeybindingLabel(action: string, mode: string | null): string | null;\n\n  /**\n   * Register a command in the command palette (Ctrl+P).\n   * \n   * Usually you should omit `context` so the command is always visible.\n   * If provided, the command is **hidden** unless your plugin has activated\n   * that context with `editor.setContext(name, true)` or the focused buffer\'s\n   * virtual mode (from `defineMode()`) matches. This is for plugin-defined\n   * contexts only (e.g. `\"tour-active\"`, `\"review-mode\"`), not built-in\n   * editor modes.\n   */\n  registerCommand(name: string, description: string, handlerName: string, context?: string | null, options?: { terminalBypass?: boolean } | null): boolean;\n\n  /**\n   * Unregister a command by name\n   */\n  unregisterCommand(name: string): boolean;\n\n  /**\n   * Set a context (for keybinding conditions)\n   */\n  setContext(name: string, active: boolean): boolean;\n\n  /**\n   * Execute a built-in action\n   */\n  executeAction(actionName: string): boolean;\n\n  /**\n   * Register a custom statusbar token.\n   * Token will be named \"plugin_name:token_name\" where plugin_name is the current plugin.\n   * Returns true if registration succeeded, false if invalid or already registered.\n   */\n  registerStatusBarElement(tokenName: string, title: string): boolean;\n\n  /**\n   * Set the value of a status-bar token for a specific buffer.\n   * The full token key sent to the editor is \"plugin_name:token_name\".\n   */\n  setStatusBarValue(bufferId: number, tokenName: string, value: string): boolean;\n\n  /**\n   * Translate a string - reads plugin name from __pluginName__ global\n   * Args is optional - can be omitted, undefined, null, or an object\n   */\n  t(key: string, ...args: unknown[]): string;\n\n  /**\n   * Get cursor position in active buffer\n   */\n  getCursorPosition(): number;\n\n  /**\n   * Get file path for a buffer\n   */\n  getBufferPath(bufferId: number): string;\n\n  /**\n   * Get buffer length in bytes\n   */\n  getBufferLength(bufferId: number): number;\n\n  /**\n   * Check if buffer has unsaved changes\n   */\n  isBufferModified(bufferId: number): boolean;\n\n  /**\n   * Save a buffer to a specific file path\n   * Used by :w filename to save unnamed buffers or save-as\n   */\n  saveBufferToPath(bufferId: number, path: string): boolean;\n\n  /**\n   * Get buffer info by ID\n   */\n  getBufferInfo(bufferId: number): BufferInfo | null;\n\n  /**\n   * Get primary cursor info for active buffer\n   */\n  getPrimaryCursor(): CursorInfo | null;\n\n  /**\n   * Get all cursors for active buffer\n   */\n  getAllCursors(): CursorInfo[];\n\n  /**\n   * Get all cursor positions as byte offsets\n   */\n  getAllCursorPositions(): number[];\n\n  /**\n   * Get viewport info for active buffer\n   */\n  getViewport(): ViewportInfo | null;\n\n  /**\n   * Total terminal dimensions in cells. Unlike `getViewport()`\n   * (which reports the active split, shrunk by any vertical\n   * split layout), this reflects the full terminal \u{2014} what a\n   * floating overlay sized by `heightPct` actually gets.\n   */\n  getScreenSize(): ScreenSize;\n\n  /**\n   * List every split with its active buffer and viewport.\n   * \n   * Plugins that need to operate on every visible buffer\n   * simultaneously (multi-split flash labels, syncing decorations\n   * across panes, \u{2026}) iterate this list rather than only seeing\n   * `getViewport()`\'s active-split data.  Order is unspecified.\n   */\n  listSplits(): SplitSnapshot[];\n\n  /**\n   * Get the line number (0-indexed) of the primary cursor\n   */\n  getCursorLine(): number;\n\n  /**\n   * Get the byte offset of the start of a line (0-indexed line number)\n   * Returns null if the line number is out of range\n   */\n  getLineStartPosition(line: number): Promise<number | null>;\n\n  /**\n   * Get the byte offset of the end of a line (0-indexed line number)\n   * Returns the position after the last character of the line (before newline)\n   * Returns null if the line number is out of range\n   */\n  getLineEndPosition(line: number): Promise<number | null>;\n\n  /**\n   * Get the total number of lines in the active buffer\n   * Returns null if buffer not found\n   */\n  getBufferLineCount(): Promise<number | null>;\n\n  /**\n   * Scroll a split to center a specific line in the viewport\n   * Line is 0-indexed (0 = first line)\n   */\n  scrollToLineCenter(splitId: number, bufferId: number, line: number): boolean;\n\n  /**\n   * Scroll any split/panel showing `buffer_id` so `line` is visible.\n   * Unlike `scrollToLineCenter`, this does not require a split id \u{2014} it\n   * updates every split\'s viewport whose active buffer is the given\n   * buffer, including inner leaves of a buffer group. Use this from\n   * a panel plugin to keep the user\'s \"selected\" row in view after\n   * arrow-key navigation (the plugin\'s own selection state isn\'t\n   * automatically reflected in the buffer cursor, so the core-driven\n   * viewport would otherwise stay put).\n   */\n  scrollBufferToLine(bufferId: number, line: number): boolean;\n\n  /**\n   * Find buffer by file path, returns buffer ID or 0 if not found\n   */\n  findBufferByPath(path: string): number;\n\n  /**\n   * Get diff between buffer content and last saved version\n   */\n  getBufferSavedDiff(bufferId: number): BufferSavedDiff | null;\n\n  /**\n   * Insert text at a position in a buffer\n   */\n  insertText(bufferId: number, position: number, text: string): boolean;\n\n  /**\n   * Delete a range from a buffer\n   */\n  deleteRange(bufferId: number, start: number, end: number): boolean;\n\n  /**\n   * Insert text at cursor position in active buffer\n   */\n  insertAtCursor(text: string): boolean;\n\n  /**\n   * Open a file, optionally at a specific line/column\n   */\n  openFile(path: string, line: number | null, column: number | null): boolean;\n\n  /**\n   * Open a file in the background \u{2014} no focus change, no\n   * active-split mutation. `windowId` defaults to the active\n   * session. Setting it to an inactive session id loads the\n   * file\'s buffer and adds it as a tab in that session\'s\n   * stashed split tree, ready to be revealed on next dive.\n   * Orchestrator uses this to populate worktree sessions with\n   * preselected files.\n   */\n  openFileInBackground(path: string, windowId?: number): boolean;\n\n  /**\n   * Open a file in a specific split\n   */\n  openFileInSplit(splitId: number, path: string, line: number, column: number): boolean;\n\n  /**\n   * Open `path` as a regular buffer in forced large-file (file-backed)\n   * mode. The file is created (empty) if missing \u{2014} designed for\n   * buffers that will be filled by a concurrent `spawnProcess` with\n   * `stdoutTo`. Resolves with the new buffer\'s id, or `null` on\n   * failure.\n   * \n   * Pair with `refreshBufferFromDisk` to grow the buffer as the\n   * streaming write advances.\n   */\n  openFileStreaming(path: string): Promise<number | null>;\n\n  /**\n   * Re-stat the file backing `bufferId` and extend the buffer if the\n   * file has grown. Resolves with the new total byte length, or\n   * `null` if the buffer has no file path or doesn\'t exist.\n   * \n   * Used to drive a streaming display: while a `spawnProcess` writes\n   * to a temp file, the plugin polls this on a timer so the buffer\n   * length tracks the file length.\n   */\n  refreshBufferFromDisk(bufferId: number): Promise<number | null>;\n\n  /**\n   * Show a buffer in the current split\n   */\n  showBuffer(bufferId: number): boolean;\n\n  /**\n   * Close a buffer\n   */\n  closeBuffer(bufferId: number): boolean;\n\n  /**\n   * Close other buffers in split\n   */\n  closeOtherBuffersInSplit(bufferId: number, splitId: number): boolean;\n\n  /**\n   * Close all buffers in split\n   */\n  closeAllBuffersInSplit(splitId: number): boolean;\n\n  /**\n   * Close buffers to right in split\n   */\n  closeBuffersToRightInSplit(bufferId: number, splitId: number): boolean;\n\n  /**\n   * Close buffers to left in split\n   */\n  closeBuffersToLeftInSplit(bufferId: number, splitId: number): boolean;\n\n  /**\n   * Move the active tab to the left in the active split\n   */\n  moveTabToLeft(): boolean;\n\n  /**\n   * Move the active tab to the right in the active split\n   */\n  moveTabToRight(): boolean;\n\n  /**\n   * Start a frame-buffer animation over an arbitrary screen region.\n   * Returns an animation id usable with `cancelAnimation`.\n   */\n  animateArea(rect: AnimationRect, kind: PluginAnimationKind): number;\n\n  /**\n   * Start an animation over the on-screen Rect currently occupied by a\n   * virtual buffer. No-op if the buffer is not visible.\n   */\n  animateVirtualBuffer(bufferId: number, kind: PluginAnimationKind): number;\n\n  /**\n   * Cancel an animation previously started via `animateArea` or\n   * `animateVirtualBuffer`. No-op if the ID is unknown or already done.\n   */\n  cancelAnimation(id: number): boolean;\n\n  /**\n   * Subscribe to an editor event\n   */\n  on(eventName: string, handlerName: string): void;\n\n  /**\n   * Unsubscribe from an event\n   */\n  off(eventName: string, handlerName: string): void;\n\n  /**\n   * Get an environment variable\n   */\n  getEnv(name: string): string | null;\n\n  /**\n   * Get current working directory\n   */\n  getCwd(): string;\n\n  /**\n   * Get the active authority\'s display label.\n   * \n   * Empty means the local (default) authority. A non-empty value\n   * means a plugin-installed or SSH authority is in effect (e.g.\n   * `\"Container:abc123def456\"` for a devcontainer). Intended as a\n   * simple \"am I already attached?\" check that survives editor\n   * restarts \u{2014} the label lives on the `Editor` state snapshot so it\n   * is fresh after the authority-transition restart flow.\n   */\n  getAuthorityLabel(): string;\n\n  /**\n   * Current Workspace Trust level for the active project: `\"restricted\"`,\n   * `\"trusted\"`, or `\"blocked\"` (empty when unavailable). Exposed to JS as\n   * `editor.workspaceTrustLevel()`. Plugins that run repo-controlled work\n   * should treat anything other than `\"trusted\"` as \"do not execute\".\n   */\n  workspaceTrustLevel(): string;\n\n  /**\n   * Whether an environment is currently active (set via `editor.setEnv`).\n   * Exposed to JS as `editor.envActive()`. Lets the env-manager plugin\n   * reflect activation and re-establish its file watch after the restart\n   * that `setEnv` triggers.\n   */\n  envActive(): boolean;\n\n  /**\n   * Join path components (variadic - accepts multiple string arguments)\n   * Always uses forward slashes for cross-platform consistency (like Node.js path.posix.join)\n   * \n   * Preserves up to 2 leading slashes, which matters on Windows: Rust\'s\n   * `Path::canonicalize` returns `\\\\?\\`-prefixed paths, and `editor.getCwd()`\n   * surfaces that to plugin code verbatim. After the backslash\u{2192}slash\n   * normalization the prefix becomes `//?/C:/...`; collapsing the leading\n   * `//` to a single `/` yields `/?/C:/...`, which every filesystem API on\n   * Windows rejects, breaking `findConfig()`-style plugin logic.\n   */\n  pathJoin(...parts: string[]): string;\n\n  /**\n   * Get directory name from path\n   */\n  pathDirname(path: string): string;\n\n  /**\n   * Get file name from path\n   */\n  pathBasename(path: string): string;\n\n  /**\n   * Get file extension\n   */\n  pathExtname(path: string): string;\n\n  /**\n   * Check if path is absolute\n   */\n  pathIsAbsolute(path: string): boolean;\n\n  /**\n   * Convert a file:// URI to a local file path.\n   * Handles percent-decoding and Windows drive letters.\n   * Returns an empty string if the URI is not a valid file URI.\n   */\n  fileUriToPath(uri: string): string;\n\n  /**\n   * Convert a local file path to a file:// URI.\n   * Handles Windows drive letters and special characters.\n   * Returns an empty string if the path cannot be converted.\n   */\n  pathToFileUri(path: string): string;\n\n  /**\n   * Get the UTF-8 byte length of a JavaScript string.\n   * \n   * JS strings are UTF-16 internally, so `str.length` returns the number of\n   * UTF-16 code units, not the number of bytes in a UTF-8 encoding.  The\n   * editor API uses byte offsets for all buffer positions (overlays, cursor,\n   * getBufferText ranges, etc.).  This helper lets plugins convert JS string\n   * lengths / regex match indices to the byte offsets the editor expects.\n   */\n  utf8ByteLength(text: string): number;\n\n  /**\n   * Check if file exists\n   */\n  fileExists(path: string): boolean;\n\n  /**\n   * Read file contents\n   */\n  readFile(path: string): string | null;\n\n  /**\n   * Write file contents\n   */\n  writeFile(path: string, content: string): boolean;\n\n  /**\n   * Read directory contents (returns array of {name, is_file, is_dir})\n   */\n  readDir(path: string): DirEntry[];\n\n  /**\n   * Create a directory (and all parent directories) recursively.\n   * Returns true if the directory was created or already exists.\n   */\n  createDir(path: string): boolean;\n\n  /**\n   * Remove a file or directory by moving it to the OS trash/recycle bin.\n   * For safety, the path must be under the OS temp directory or the Fresh\n   * config directory. Returns true on success.\n   */\n  removePath(path: string): boolean;\n\n  /**\n   * Rename/move a file or directory. Returns true on success.\n   * Falls back to copy then trash for cross-filesystem moves.\n   */\n  renamePath(from: string, to: string): boolean;\n\n  /**\n   * Copy a file or directory recursively to a new location.\n   * Returns true on success.\n   */\n  copyPath(from: string, to: string): boolean;\n\n  /**\n   * Get the OS temporary directory path.\n   */\n  getTempDir(): string;\n\n  /**\n   * Parse a JSONC (JSON with comments) string into a JS value.\n   * \n   * Accepts the JSONC superset: line and block comments, trailing\n   * commas, single-quoted strings, and unquoted object keys \u{2014} matching\n   * devcontainer.json / tsconfig.json / VS Code settings.json.\n   * \n   * Throws a JS error (catchable with try/catch) when the input is not\n   * valid JSONC, like `JSON.parse` does for invalid JSON.\n   */\n  parseJsonc(text: string): unknown;\n\n  /**\n   * Get current config as JS object.\n   * \n   * The snapshot holds an `Arc<serde_json::Value>` that was serialized\n   * on the editor side the last time the underlying `Arc<Config>`\n   * changed. Cloning the Arc inside the read lock is a refcount bump;\n   * the actual walk into the JS runtime happens outside the lock.\n   */\n  getConfig(): unknown;\n\n  /**\n   * Get user config as JS object. Same Arc-clone pattern as `get_config`.\n   */\n  getUserConfig(): unknown;\n\n  /**\n   * Declare a boolean config field for the calling plugin.\n   * \n   * Validates `options` synchronously: the JS call throws if any\n   * unknown key is present or if `default` isn\'t a boolean. The\n   * Settings UI grows a \"Plugin Settings \u{2192} <plugin>\" sub-category\n   * containing a toggle for this field. Returns the current value\n   * (user-set if present, otherwise the declared `default`).\n   */\n  defineConfigBoolean(name: string, options: { default: boolean; description?: string }): boolean;\n\n  /**\n   * Declare an integer config field for the calling plugin. Throws on\n   * invalid options or if the default falls outside `minimum/maximum`.\n   */\n  defineConfigInteger(name: string, options: { default: number; description?: string; minimum?: number; maximum?: number }): number;\n\n  /**\n   * Declare a floating-point number config field. Throws on bad\n   * options or default outside `minimum/maximum`.\n   */\n  defineConfigNumber(name: string, options: { default: number; description?: string; minimum?: number; maximum?: number }): number;\n\n  /**\n   * Declare a free-form string config field.\n   */\n  defineConfigString(name: string, options: { default: string; description?: string }): string;\n\n  /**\n   * Declare an array-of-strings config field (e.g. a list of\n   * patterns). The Settings UI renders this as a list editor.\n   */\n  defineConfigStringArray(name: string, options: { default: string[]; description?: string }): string[];\n\n  /**\n   * Get the calling plugin\'s settings as a JS object.\n   * \n   * Returns the merged value at `config.plugins.<plugin_name>.settings`.\n   * The shape comes from whatever the plugin declared via\n   * `editor.definePluginConfig(...)` (defaults pre-populated by the\n   * host, user overrides on top from the Settings UI). Returns `null`\n   * if the plugin hasn\'t declared a schema and has no user-set value.\n   */\n  getPluginConfig(): unknown;\n\n  /**\n   * Reload configuration from file\n   */\n  reloadConfig(): void;\n\n  /**\n   * Set a single config setting in the runtime layer for this session.\n   * \n   * `path` is dot-separated (e.g. `\"editor.tab_size\"`). `value` is any JSON\n   * value in the shape the setting expects. The write lives in an\n   * in-memory layer scoped to the calling plugin \u{2014} it does not modify\n   * `config.json`, and unloading the plugin (or reloading init.ts) drops\n   * it. Intended use is `init.ts` running a conditional:\n   * `if (editor.getEnv(\"SSH_TTY\")) editor.setSetting(\"terminal.mouse\", false);`\n   * \n   * Returns `true` if the write was queued. The actual update is\n   * asynchronous; a subsequent `getConfig()` will reflect it after the\n   * editor processes the command.\n   */\n  setSetting(path: string, value: unknown): boolean;\n\n  /**\n   * Reload theme registry from disk\n   * Call this after installing theme packages or saving new themes\n   */\n  reloadThemes(): void;\n\n  /**\n   * Reload theme registry and apply a theme atomically\n   */\n  reloadAndApplyTheme(themeName: string): void;\n\n  /**\n   * Register a TextMate grammar file for a language\n   * The grammar will be pending until reload_grammars() is called\n   */\n  registerGrammar(language: string, grammarPath: string, extensions: string[]): boolean;\n\n  /**\n   * Register language configuration (comment prefix, indentation, formatter)\n   */\n  registerLanguageConfig(language: string, config: LanguagePackConfig): boolean;\n\n  /**\n   * Register an LSP server for a language\n   */\n  registerLspServer(language: string, config: LspServerPackConfig): boolean;\n\n  /**\n   * Reload the grammar registry to apply registered grammars (async)\n   * Call this after registering one or more grammars.\n   * Returns a Promise that resolves when the grammar rebuild completes.\n   */\n  reloadGrammars(): Promise<void>;\n\n  /**\n   * Get the directory where this plugin\'s files are stored.\n   * For package plugins this is `<plugins_dir>/packages/<plugin_name>/`.\n   */\n  getPluginDir(): string;\n\n  /**\n   * Get config directory path\n   */\n  getConfigDir(): string;\n\n  /**\n   * Get the persistent data directory path (DirectoryContext::data_dir).\n   * Intended for plugin state that should outlive a single session \u{2014} e.g.\n   * review-diff comments keyed off git state.\n   */\n  getDataDir(): string;\n\n  /**\n   * Get themes directory path\n   */\n  getThemesDir(): string;\n\n  /**\n   * Apply a theme by name\n   */\n  applyTheme(themeName: string): boolean;\n\n  /**\n   * Override theme colors in-memory for the running session. `overrides`\n   * is a JS object mapping `\"section.field\"` keys (same namespace as\n   * `getThemeSchema`) to `[r, g, b]` triplets (0\u{2013}255 each).\n   * \n   * Unknown keys are dropped silently; out-of-range values are clamped\n   * to `0..=255`. Overrides survive until the next `applyTheme` call\n   * (which replaces the whole `Theme`). Intended for fast animation\n   * loops from `init.ts` \u{2014} no disk I/O, no theme-registry rescan.\n   */\n  overrideThemeColors(overrides: unknown): boolean;\n\n  /**\n   * Get theme schema as JS object\n   */\n  getThemeSchema(): unknown;\n\n  /**\n   * Get list of builtin themes as JS object\n   */\n  getBuiltinThemes(): unknown;\n\n  /**\n   * Full theme registry (builtins + user themes + packages + bundles).\n   * Keyed by canonical registry key; each value carries `_key` / `_pack`.\n   */\n  getAllThemes(): unknown;\n\n  /**\n   * Delete a custom theme (alias for deleteThemeSync)\n   */\n  deleteTheme(name: string): boolean;\n\n  /**\n   * Get theme data (JSON) by name from the in-memory cache\n   */\n  getThemeData(name: string): unknown;\n\n  /**\n   * Save a theme file to the user themes directory, returns the saved path\n   */\n  saveThemeFile(name: string, content: string): string;\n\n  /**\n   * Check if a user theme file exists\n   */\n  themeFileExists(name: string): boolean;\n\n  /**\n   * Get file stat information\n   */\n  fileStat(path: string): unknown;\n\n  /**\n   * Check if a background process is still running\n   */\n  isProcessRunning(processId: number): boolean;\n\n  /**\n   * Kill a process by ID (alias for killBackgroundProcess)\n   */\n  killProcess(processId: number): boolean;\n\n  /**\n   * Translate a key for a specific plugin\n   */\n  pluginTranslate(pluginName: string, key: string, args?: Record<string, unknown>): string;\n\n  /**\n   * Create a composite buffer (async)\n   * \n   * Uses typed CreateCompositeBufferOptions - serde validates field names at runtime\n   * via `deny_unknown_fields` attribute\n   */\n  createCompositeBuffer(opts: TsCreateCompositeBufferOptions): Promise<number>;\n\n  /**\n   * Update alignment hunks for a composite buffer\n   * \n   * Uses typed Vec<CompositeHunk> - serde validates field names at runtime\n   */\n  updateCompositeAlignment(bufferId: number, hunks: TsCompositeHunk[]): boolean;\n\n  /**\n   * Close a composite buffer\n   */\n  closeCompositeBuffer(bufferId: number): boolean;\n\n  /**\n   * Force-materialize render-dependent state (like `layoutIfNeeded` in UIKit).\n   * After calling this, commands that depend on view state created during\n   * rendering (e.g., `compositeNextHunk`) will work correctly.\n   */\n  flushLayout(): boolean;\n\n  /**\n   * Navigate to the next hunk in a composite buffer\n   */\n  compositeNextHunk(bufferId: number): boolean;\n\n  /**\n   * Navigate to the previous hunk in a composite buffer\n   */\n  compositePrevHunk(bufferId: number): boolean;\n\n  /**\n   * Request syntax highlights for a buffer range (async)\n   */\n  getHighlights(bufferId: number, start: number, end: number): Promise<TsHighlightSpan[]>;\n\n  /**\n   * Add an overlay with styling options\n   * \n   * Colors can be specified as RGB arrays `[r, g, b]` or theme key strings.\n   * Theme keys are resolved at render time, so overlays update with theme changes.\n   * \n   * Theme key examples: \"ui.status_bar_fg\", \"editor.selection_bg\", \"syntax.keyword\"\n   * \n   * Options: fg, bg (RGB array or theme key string), bold, italic, underline,\n   * strikethrough, extend_to_line_end (all booleans, default false).\n   * \n   * Example usage in TypeScript:\n   * ```typescript\n   * editor.addOverlay(bufferId, \"my-namespace\", 0, 10, {\n   * fg: \"syntax.keyword\",           // theme key\n   * bg: [40, 40, 50],               // RGB array\n   * bold: true,\n   * strikethrough: true,\n   * });\n   * ```\n   */\n  addOverlay(bufferId: number, namespace: string, start: number, end: number, options: Record<string, unknown>): boolean;\n\n  /**\n   * Clear all overlays in a namespace\n   */\n  clearNamespace(bufferId: number, namespace: string): boolean;\n\n  /**\n   * Clear all overlays from a buffer\n   */\n  clearAllOverlays(bufferId: number): boolean;\n\n  /**\n   * Clear all overlays that overlap with a byte range\n   */\n  clearOverlaysInRange(bufferId: number, start: number, end: number): boolean;\n\n  /**\n   * Remove an overlay by its handle\n   */\n  removeOverlay(bufferId: number, handle: string): boolean;\n\n  /**\n   * Add a conceal range that hides or replaces a byte range during rendering\n   */\n  addConceal(bufferId: number, namespace: string, start: number, end: number, replacement: string | null): boolean;\n\n  /**\n   * Clear all conceal ranges in a namespace\n   */\n  clearConcealNamespace(bufferId: number, namespace: string): boolean;\n\n  /**\n   * Clear all conceal ranges that overlap with a byte range\n   */\n  clearConcealsInRange(bufferId: number, start: number, end: number): boolean;\n\n  /**\n   * Add a collapsed fold range. Hides bytes [start, end) from\n   * rendering \u{2014} the line containing `start - 1` (the fold \"header\")\n   * stays visible, while subsequent lines covered by the range are\n   * skipped.\n   */\n  addFold(bufferId: number, start: number, end: number, placeholder?: string): boolean;\n\n  /**\n   * Clear every collapsed fold range on the buffer.\n   */\n  clearFolds(bufferId: number): boolean;\n\n  /**\n   * Publish a set of toggleable fold ranges on the buffer. Same\n   * shape an LSP `foldingRange` response would take. Unlike\n   * `addFold`, this does *not* pre-collapse anything \u{2014} the\n   * standard fold-toggle keybinding finds the range under the\n   * cursor and collapses or expands it on demand. Replacing call\n   * replaces the prior set.\n   * \n   * `ranges` is a JS array of objects shaped\n   * `{ startLine, endLine, kind? }` (lines are 0-indexed).\n   * `kind` is one of `\"comment\"`, `\"imports\"`, `\"region\"` per\n   * the LSP spec; omitted/unknown values are accepted as plain\n   * folds.\n   */\n  setFoldingRanges(bufferId: number, rangesArr: Record<string, unknown>[]): boolean;\n\n  /**\n   * Add a soft break point for marker-based line wrapping\n   */\n  addSoftBreak(bufferId: number, namespace: string, position: number, indent: number): boolean;\n\n  /**\n   * Clear all soft breaks in a namespace\n   */\n  clearSoftBreakNamespace(bufferId: number, namespace: string): boolean;\n\n  /**\n   * Clear all soft breaks that fall within a byte range\n   */\n  clearSoftBreaksInRange(bufferId: number, start: number, end: number): boolean;\n\n  /**\n   * Submit a view transform for a buffer/split\n   * \n   * Accepts tokens in the simple format:\n   * {kind: \"text\"|\"newline\"|\"space\"|\"break\", text: \"...\", sourceOffset: N, style?: {...}}\n   * \n   * Also accepts the TypeScript-defined format for backwards compatibility:\n   * {kind: {Text: \"...\"} | \"Newline\" | \"Space\" | \"Break\", source_offset: N, style?: {...}}\n   */\n  submitViewTransform(bufferId: number, splitId: number | null, start: number, end: number, tokens: Record<string, unknown>[], layoutHints?: Record<string, unknown>): boolean;\n\n  /**\n   * Clear view transform for a buffer/split\n   */\n  clearViewTransform(bufferId: number, splitId: number | null): boolean;\n\n  /**\n   * Set layout hints (compose width, column guides) for a buffer/split\n   * without going through the view_transform pipeline.\n   */\n  setLayoutHints(bufferId: number, splitId: number | null, hints: LayoutHints): boolean;\n\n  /**\n   * Set file explorer decorations for a namespace\n   */\n  setFileExplorerDecorations(namespace: string, decorations: Record<string, unknown>[]): boolean;\n\n  /**\n   * Clear file explorer decorations for a namespace\n   */\n  clearFileExplorerDecorations(namespace: string): boolean;\n\n  /**\n   * Add virtual text (inline text that doesn\'t exist in the buffer)\n   */\n  addVirtualText(bufferId: number, virtualTextId: string, position: number, text: string, r: number, g: number, b: number, before: boolean, useBg: boolean): boolean;\n\n  /**\n   * Remove a virtual text by ID\n   */\n  removeVirtualText(bufferId: number, virtualTextId: string): boolean;\n\n  /**\n   * Add styled virtual text \u{2014} richer form of `addVirtualText` whose\n   * `options` accepts an `addOverlay`-style record: `fg`/`bg` may\n   * be RGB arrays or theme-key strings, plus `bold`/`italic`. Theme\n   * keys are resolved at render time so the label follows theme\n   * changes live.\n   */\n  addVirtualTextStyled(bufferId: number, virtualTextId: string, position: number, text: string, options: Record<string, unknown>, before: boolean): boolean;\n\n  /**\n   * Remove virtual texts whose ID starts with the given prefix\n   */\n  removeVirtualTextsByPrefix(bufferId: number, prefix: string): boolean;\n\n  /**\n   * Clear all virtual texts from a buffer\n   */\n  clearVirtualTexts(bufferId: number): boolean;\n\n  /**\n   * Clear all virtual texts in a namespace\n   */\n  clearVirtualTextNamespace(bufferId: number, namespace: string): boolean;\n\n  /**\n   * Add a virtual line (full line above/below a position)\n   * \n   * The `options` object accepts:\n   * * `fg`, `bg` \u{2014} either an `[r, g, b]` array (each `0..=255`) or a\n   * theme-key string (e.g. `\"editor.line_number_fg\"`).  Theme keys\n   * are resolved at render time so the line follows theme changes.\n   * Both default to `null` (no foreground / transparent background).\n   * * `gutterGlyph` \u{2014} optional single character (any short string)\n   * rendered in the line-number column on this virtual line\'s\n   * first visual row. Use to mark e.g. a deletion line with \"-\"\n   * so the indicator sits next to the deleted content instead\n   * of on the following source line.\n   * * `gutterColor` \u{2014} color for `gutterGlyph`, same shape as\n   * `fg`/`bg`. Falls back to the theme\'s line-number fg.\n   */\n  addVirtualLine(bufferId: number, position: number, text: string, options: Record<string, unknown>, above: boolean, namespace: string, priority: number): boolean;\n\n  /**\n   * Show a prompt and wait for user input (async)\n   * Returns the user input or null if cancelled\n   */\n  prompt(label: string, initialValue: string): Promise<string | null>;\n\n  /**\n   * Start an interactive prompt.\n   * \n   * When `floatingOverlay` is true, the editor renders the prompt\n   * and its suggestions inside a centred floating frame instead of\n   * the bottom minibuffer row (issue #1796 \u{2014} Live Grep). The flag\n   * is rendering-only; confirm/cancel/hooks behave identically to a\n   * non-overlay prompt of the same `promptType`.\n   */\n  startPrompt(label: string, promptType: string, floatingOverlay?: boolean): boolean;\n\n  /**\n   * Begin a key-capture window for the calling plugin.\n   * \n   * Pair with `endKeyCapture()` around any `getNextKey()` loop.\n   * While capture is active, keys arriving between two\n   * `getNextKey()` calls are buffered in-order rather than\n   * falling through to the buffer / mode bindings, so fast typing,\n   * pastes, or held-key auto-repeat are delivered losslessly.\n   * Without this, a plugin\'s input loop has a race where keys\n   * typed while the plugin is mid-redraw can leak into the editor.\n   */\n  beginKeyCapture(): boolean;\n\n  /**\n   * End the key-capture window and discard any unconsumed buffered\n   * keys.  Call from a `finally` block so capture is released even\n   * if the plugin\'s loop throws.\n   */\n  endKeyCapture(): boolean;\n\n  /**\n   * Wait for the next keypress and resolve with a `KeyEventPayload`.\n   * \n   * While the returned promise is pending the editor consumes the\n   * next key and resolves it; the key does not propagate to mode\n   * bindings or other dispatch. Multiple in-flight requests across\n   * plugins are FIFO. Designed for short input loops (flash labels,\n   * vi find-char, replace-char) that would otherwise need to bind\n   * every printable key in `defineMode`.\n   * \n   * For lossless capture against fast typing or paste, wrap the\n   * loop with `beginKeyCapture()` / `endKeyCapture()`.\n   */\n  getNextKey(): Promise<KeyEventPayload>;\n\n  /**\n   * Start a prompt with initial value. See `startPrompt` for the\n   * meaning of `floatingOverlay`.\n   */\n  startPromptWithInitial(label: string, promptType: string, initialValue: string, floatingOverlay?: boolean): boolean;\n\n  /**\n   * Set suggestions for the current prompt\n   * \n   * Uses typed Vec<Suggestion> - serde validates field names at runtime\n   */\n  setPromptSuggestions(suggestions: PromptSuggestion[]): boolean;\n\n  setPromptInputSync(sync: boolean): boolean;\n\n  /**\n   * Set the title shown in the floating-overlay prompt\'s frame\n   * header (issue #1796) as styled segments. Each segment\n   * carries optional `Partial<OverlayOptions>`, the same\n   * styling primitive used by virtual text \u{2014} plugins mark\n   * keybinding hints with `{ fg: \"ui.help_key_fg\" }`,\n   * separators with `{ fg: \"ui.popup_border_fg\" }`, etc. Pass\n   * an empty array to clear the title and fall back to the\n   * prompt-type default. Has no visible effect on non-overlay\n   * prompts.\n   */\n  setPromptTitle(title: StyledText[]): boolean;\n\n  /**\n   * Set the footer chrome row of the floating-overlay prompt\'s\n   * results pane. Plugins use this for hotkey-hint banners\n   * (Orchestrator\'s `[n] new   [d] dive   [Esc] close` row).\n   * Empty array clears the footer. Has no visible effect on\n   * non-overlay prompts.\n   */\n  setPromptFooter(footer: StyledText[]): boolean;\n\n  /**\n   * Override the currently-highlighted suggestion row in the\n   * open prompt. The editor clamps `index` to the suggestion\n   * list\'s bounds and the renderer scrolls it into view on\n   * the next frame. No-op when no prompt is open or the\n   * suggestion list is empty. Typical use: re-opening a\n   * picker and pre-selecting the entry the user last acted on\n   * (Orchestrator highlights the active session).\n   */\n  setPromptSelectedIndex(index: number): boolean;\n\n  /**\n   * Define a buffer mode (takes bindings as array of [key, command] pairs)\n   */\n  defineMode(name: string, bindingsArr: string[][], readOnly?: boolean, allowTextInput?: boolean, inheritNormalBindings?: boolean): boolean;\n\n  /**\n   * Set the global editor mode\n   */\n  setEditorMode(mode: string | null): boolean;\n\n  /**\n   * Get the current editor mode\n   */\n  getEditorMode(): string | null;\n\n  /**\n   * Close a split\n   */\n  closeSplit(splitId: number): boolean;\n\n  /**\n   * Set the buffer displayed in a split\n   */\n  setSplitBuffer(splitId: number, bufferId: number): boolean;\n\n  /**\n   * Focus a specific split\n   */\n  focusSplit(splitId: number): boolean;\n\n  /**\n   * Create a new editor session rooted at `root`. `root` must be\n   * an absolute path; relative paths are rejected by the editor\n   * (logged, no session created). The new session\'s id is\n   * reported via the `window_created` hook payload \u{2014} plugins\n   * that need the id should listen for that event rather than\n   * polling `listWindows`.\n   * \n   * Returns `false` only when the IPC channel to the editor is\n   * closed (editor is shutting down).\n   */\n  createWindow(root: string, label: string): boolean;\n\n  /**\n   * Make the session with id `id` the active one. No-op if\n   * already active. Errors (id not found) are logged on the\n   * editor side; the JS caller can verify by reading\n   * `activeWindow()` after.\n   */\n  setActiveWindow(id: number): boolean;\n\n  /**\n   * Close session `id`. Refuses to close the active session or\n   * the base session (id 1). Logs and no-ops on failure.\n   */\n  closeWindow(id: number): boolean;\n\n  /**\n   * Eagerly initialise an inactive session\'s per-session state\n   * (file tree walk, ignore matcher, etc.) without diving.\n   * No-op for the active session or unknown id.\n   */\n  prewarmWindow(id: number): boolean;\n\n  /**\n   * Register a `notify`-backed watch on `path`. Returns a\n   * promise that resolves to a numeric `handle` (also passed\n   * in subsequent `path_changed` event payloads). The promise\n   * rejects on `notify` errors (path missing, kernel limit).\n   * \n   * `recursive` defaults to `false`. Non-recursive watches\n   * cover the path itself plus its direct children for\n   * directories \u{2014} see `services/file_watcher.rs` for the\n   * rationale.\n   */\n  watchPath(path: string, recursive?: boolean): Promise<number>;\n\n  /**\n   * Drop a watcher by its handle. Unknown handles are\n   * silently ignored.\n   */\n  unwatchPath(handle: number): boolean;\n\n  /**\n   * Tell the editor that the floating-overlay prompt\'s\n   * preview pane should render the entire split tree of\n   * session `id` natively. `0` (or any unknown id) clears the\n   * override and the preview falls back to the existing\n   * path-based phantom-leaf renderer.\n   * \n   * Orchestrator calls this on each prompt-selection-change so\n   * the right pane shows the highlighted session\'s full\n   * editor UI live \u{2014} splits, terminals, syntax highlighting,\n   * decorations \u{2014} at native rendering cost.\n   */\n  previewWindowInRect(id: number): boolean;\n\n  /**\n   * Clear the session-preview override. Equivalent to\n   * `previewWindowInRect(0)` but reads better at call sites.\n   */\n  clearWindowPreview(): boolean;\n\n  /**\n   * All editor sessions, sorted by id (creation order). Always\n   * non-empty (the base session is always present).\n   */\n  listWindows(): WindowInfo[];\n\n  /**\n   * The currently active session id. Always present in\n   * `listWindows()`.\n   */\n  activeWindow(): number;\n\n  /**\n   * Set scroll position of a split\n   */\n  setSplitScroll(splitId: number, topByte: number): boolean;\n\n  /**\n   * Set the ratio of a split (0.0 to 1.0, 0.5 = equal)\n   */\n  setSplitRatio(splitId: number, ratio: number): boolean;\n\n  /**\n   * Set a label on a split (e.g., \"sidebar\")\n   */\n  setSplitLabel(splitId: number, label: string): boolean;\n\n  /**\n   * Remove a label from a split\n   */\n  clearSplitLabel(splitId: number): boolean;\n\n  /**\n   * Find a split by label (async)\n   */\n  getSplitByLabel(label: string): Promise<number | null>;\n\n  /**\n   * Distribute all splits evenly\n   */\n  distributeSplitsEvenly(): boolean;\n\n  /**\n   * Set cursor position in a buffer\n   */\n  setBufferCursor(bufferId: number, position: number): boolean;\n\n  /**\n   * Toggle whether the editor draws a native caret in this buffer.\n   * \n   * Buffer-group panel buffers default to `show_cursors = false`, which\n   * also blocks all native movement actions in `action_to_events`. Plugins\n   * that want native cursor motion in a panel (e.g. magit-style row\n   * navigation) call this with `true` after `createBufferGroup` returns.\n   */\n  setBufferShowCursors(bufferId: number, show: boolean): boolean;\n\n  /**\n   * Set a line indicator in the gutter\n   */\n  setLineIndicator(bufferId: number, line: number, namespace: string, symbol: string, r: number, g: number, b: number, priority: number): boolean;\n\n  /**\n   * Batch set line indicators in the gutter\n   */\n  setLineIndicators(bufferId: number, lines: number[], namespace: string, symbol: string, r: number, g: number, b: number, priority: number): boolean;\n\n  /**\n   * Clear line indicators in a namespace\n   */\n  clearLineIndicators(bufferId: number, namespace: string): boolean;\n\n  /**\n   * Enable or disable line numbers for a buffer\n   */\n  setLineNumbers(bufferId: number, enabled: boolean): boolean;\n\n  /**\n   * Set the view mode for a buffer (\"source\" or \"compose\")\n   */\n  setViewMode(bufferId: number, mode: string): boolean;\n\n  /**\n   * Enable or disable line wrapping for a buffer/split\n   */\n  setLineWrap(bufferId: number, splitId: number | null, enabled: boolean): boolean;\n\n  /**\n   * Set plugin-managed per-buffer view state (write-through to snapshot + command for persistence)\n   */\n  setViewState(bufferId: number, key: string, value: unknown): boolean;\n\n  /**\n   * Get plugin-managed per-buffer view state (reads from snapshot)\n   */\n  getViewState(bufferId: number, key: string): unknown;\n\n  /**\n   * Set plugin-managed global state (write-through to snapshot + command for persistence).\n   * State is automatically isolated per plugin using the plugin\'s name.\n   * TODO: Need to think about plugin isolation / namespacing strategy for these APIs.\n   */\n  setGlobalState(key: string, value: unknown): boolean;\n\n  /**\n   * Get plugin-managed global state (reads from snapshot).\n   * State is automatically isolated per plugin using the plugin\'s name.\n   * TODO: Need to think about plugin isolation / namespacing strategy for these APIs.\n   */\n  getGlobalState(key: string): unknown;\n\n  /**\n   * Set per-session state on the **active** session. Same\n   * shape as `setGlobalState` (write-through to snapshot +\n   * dispatched to editor; null/undefined deletes), but the\n   * underlying storage lives on `Session.plugin_state` and\n   * swaps with the rest of session state on `setActiveWindow`.\n   * Plugins that genuinely want per-project state use this;\n   * Orchestrator itself uses `setGlobalState` because its session\n   * list lives above session boundaries.\n   */\n  setWindowState(key: string, value: unknown): boolean;\n\n  /**\n   * Get per-session state from the **active** session\n   * (snapshot read). `undefined` if missing.\n   */\n  getWindowState(key: string): unknown;\n\n  /**\n   * Create a scroll sync group for anchor-based synchronized scrolling\n   */\n  createScrollSyncGroup(groupId: number, leftSplit: number, rightSplit: number): boolean;\n\n  /**\n   * Set sync anchors for a scroll sync group\n   */\n  setScrollSyncAnchors(groupId: number, anchors: number[][]): boolean;\n\n  /**\n   * Remove a scroll sync group\n   */\n  removeScrollSyncGroup(groupId: number): boolean;\n\n  /**\n   * Execute multiple actions in sequence\n   * \n   * Takes typed ActionSpec array - serde validates field names at runtime\n   */\n  executeActions(actions: ActionSpec[]): boolean;\n\n  /**\n   * Show an action popup\n   * \n   * Takes a typed ActionPopupOptions struct - serde validates field names at runtime\n   */\n  showActionPopup(opts: ActionPopupOptions): boolean;\n\n  /**\n   * Contribute (or replace, or clear) menu rows for the LSP-Servers\n   * popup. Pass an empty `items` to clear this plugin\'s slice for\n   * the given language. See `PluginCommand::SetLspMenuContributions`.\n   */\n  setLspMenuContributions(pluginId: string, language: string, items: TsLspMenuItem[]): boolean;\n\n  /**\n   * Disable LSP for a specific language\n   */\n  disableLspForLanguage(language: string): boolean;\n\n  /**\n   * Restart LSP server for a specific language\n   */\n  restartLspForLanguage(language: string): boolean;\n\n  /**\n   * Set the workspace root URI for a specific language\'s LSP server\n   * This allows plugins to specify project roots (e.g., directory containing .csproj)\n   */\n  setLspRootUri(language: string, uri: string): boolean;\n\n  /**\n   * Get all diagnostics from LSP\n   */\n  getAllDiagnostics(): JsDiagnostic[];\n\n  /**\n   * Get registered event handlers for an event\n   */\n  getHandlers(eventName: string): string[];\n\n  /**\n   * Create a virtual buffer in current split (async, returns buffer and split IDs)\n   */\n  createVirtualBuffer(opts: CreateVirtualBufferOptions): Promise<VirtualBufferResult>;\n\n  /**\n   * Create a virtual buffer in a new split (async, returns buffer and split IDs)\n   */\n  createVirtualBufferInSplit(opts: CreateVirtualBufferInSplitOptions): Promise<VirtualBufferResult>;\n\n  /**\n   * Create a virtual buffer in an existing split (async, returns buffer and split IDs)\n   */\n  createVirtualBufferInExistingSplit(opts: CreateVirtualBufferInExistingSplitOptions): Promise<VirtualBufferResult>;\n\n  /**\n   * Set the content of a panel within a buffer group\n   */\n  setPanelContent(groupId: number, panelName: string, entriesArr: Record<string, unknown>[]): boolean;\n\n  /**\n   * Close a buffer group\n   */\n  closeBufferGroup(groupId: number): boolean;\n\n  /**\n   * Focus a specific panel within a buffer group\n   */\n  focusBufferGroupPanel(groupId: number, panelName: string): boolean;\n\n  /**\n   * Re-point a buffer-group\'s panel at a different buffer id.\n   * \n   * Streaming plugins (e.g. git-log) allocate one file-backed\n   * buffer per item and call this on navigation to swap which\n   * buffer the panel displays \u{2014} instead of mutating a single\n   * shared buffer\'s contents. Resolves with `true` on success.\n   */\n  setBufferGroupPanelBuffer(groupId: number, panelName: string, bufferId: number): Promise<boolean>;\n\n  /**\n   * Set virtual buffer content (takes array of entry objects)\n   * \n   * Note: entries should be TextPropertyEntry[] - uses manual parsing for HashMap support\n   */\n  setVirtualBufferContent(bufferId: number, entriesArr: Record<string, unknown>[]): boolean;\n\n  /**\n   * Get text properties at cursor position (returns JS array)\n   */\n  getTextPropertiesAtCursor(bufferId: number): TextPropertiesAtCursor;\n\n  /**\n   * Mount a declarative widget panel inside a virtual buffer.\n   * \n   * `spec` is a `WidgetSpec` JSON tree (see fresh.d.ts for the\n   * shape). The host renders the spec into the buffer; subsequent\n   * `updateWidgetPanel` calls re-render the panel against the\n   * previously-mounted spec.\n   * \n   * Returns true on successful queue, false if the IPC channel is\n   * closed.\n   */\n  mountWidgetPanel(panelId: number, bufferId: number, specObj: unknown): boolean;\n\n  /**\n   * Replace the spec of a previously-mounted widget panel.\n   * No-op if the panel id was never mounted.\n   */\n  updateWidgetPanel(panelId: number, specObj: unknown): boolean;\n\n  /**\n   * Unmount a previously-mounted widget panel. The plugin retains\n   * ownership of the underlying virtual buffer.\n   */\n  unmountWidgetPanel(panelId: number): boolean;\n\n  /**\n   * Route a keystroke / nav action to the panel\'s focused widget.\n   * \n   * `action` is a `WidgetAction` JSON object \u{2014} see fresh.d.ts for\n   * the shapes (`{kind: \"focusAdvance\", delta: 1}` etc.). Plugin\'s\n   * `defineMode` bindings dispatch into here for keys handled by\n   * the widget layer; the host runtime acts on the panel\'s\n   * currently focused widget and fires `widget_event` as\n   * appropriate.\n   */\n  widgetCommand(panelId: number, actionObj: unknown): boolean;\n\n  /**\n   * Apply a targeted mutation to a mounted widget panel \u{2014} the\n   * IPC fast path. Use instead of `updateWidgetPanel` when the\n   * model change touches a single widget; the host applies the\n   * mutation in place without re-transmitting the full spec.\n   * See `WidgetMutation` in fresh.d.ts for the shapes.\n   */\n  widgetMutate(panelId: number, mutationObj: unknown): boolean;\n\n  /**\n   * Mount a declarative widget panel as a centered floating\n   * overlay (not bound to any virtual buffer).\n   */\n  mountFloatingWidget(panelId: number, specObj: unknown, widthPct: number, heightPct: number): boolean;\n\n  /**\n   * Replace the spec of the currently-mounted floating widget panel.\n   */\n  updateFloatingWidget(panelId: number, specObj: unknown): boolean;\n\n  /**\n   * Tear down the floating widget panel.\n   */\n  unmountFloatingWidget(panelId: number): boolean;\n\n  /**\n   * Spawn a process (async, returns request_id)\n   * \n   * Optional 4th argument `stdoutTo: string` pipes the child\'s stdout\n   * directly into the named file instead of buffering it. The\n   * resolved `SpawnResult.stdout` is empty in that case; the bytes\n   * land on disk for `openFile` to pick up as a file-backed buffer.\n   */\n  spawnProcess(command: string, args: string[], cwd?: string, stdoutTo?: string): ProcessHandle<SpawnResult>;\n\n  /**\n   * Spawn a process on the host regardless of the active authority.\n   * \n   * Intended for plugin internals that must run host-side work\n   * (e.g. `devcontainer up`) before installing an authority that\n   * would otherwise route the spawn elsewhere. Same calling shape\n   * as `spawnProcess`.\n   */\n  spawnHostProcess(command: string, args: string[], cwd?: string): ProcessHandle<SpawnResult>;\n\n  /**\n   * Install a new authority via an opaque payload.\n   * \n   * The payload is a JS object describing filesystem + spawner +\n   * terminal wrapper + display label. The canonical schema lives in\n   * the `AuthorityPayload` type in `fresh-editor`; plugins should\n   * hand-build objects that match it. Fire-and-forget: the editor\n   * restarts as part of the transition, so the plugin is reloaded\n   * before any follow-up work can run on this call\'s return value.\n   */\n  setAuthority(payload: AuthorityPayload): boolean;\n\n  /**\n   * Restore the default local authority. Same restart semantics as\n   * `setAuthority`.\n   */\n  clearAuthority(): void;\n\n  /**\n   * Activate an environment: set the live env recipe (`snippet` run in\n   * `dir`). Applied to every spawn, re-evaluated on demand \u{2014} no restart.\n   * Honored only when the workspace is Trusted.\n   */\n  setEnv(snippet: string, dir: string | null): void;\n\n  /**\n   * Deactivate the environment \u{2014} spawns return to the inherited env.\n   */\n  clearEnv(): void;\n\n  /**\n   * Override the Remote Indicator\'s displayed state. Plugins call\n   * this to surface lifecycle transitions that the authority layer\n   * doesn\'t know about yet \u{2014} \"Connecting\" while `devcontainer up`\n   * runs, \"FailedAttach\" after a non-zero exit, etc.\n   * \n   * Accepts a tagged JS object:\n   * ```ts\n   * editor.setRemoteIndicatorState({ kind: \"connecting\", label: \"Building\" });\n   * editor.setRemoteIndicatorState({ kind: \"failed_attach\", error: \"exit 1\" });\n   * editor.setRemoteIndicatorState({ kind: \"connected\", label: \"Container:abc\" });\n   * editor.setRemoteIndicatorState({ kind: \"local\" });\n   * ```\n   * \n   * The override sticks until replaced or cleared via\n   * `clearRemoteIndicatorState`. Editor restart (e.g. on\n   * `setAuthority`) resets it \u{2014} plugins must reassert after a\n   * post-restart init if they want the override to persist.\n   */\n  setRemoteIndicatorState(state: RemoteIndicatorStatePayload): boolean;\n\n  /**\n   * Drop any active Remote Indicator override. Safe to call even\n   * without a prior `setRemoteIndicatorState`.\n   */\n  clearRemoteIndicatorState(): void;\n\n  /**\n   * Fetch a URL over HTTP(S) and stream the response body into `target_path`.\n   * \n   * Resolves with a `SpawnResult`-shaped value: `exit_code` is `0` on a\n   * 2xx response (file written), the HTTP status code on non-2xx\n   * (target file untouched), and `-1` on transport errors. `stderr`\n   * carries an error message in the non-success cases; `stdout` is\n   * always empty.\n   * \n   * This uses the editor\'s built-in HTTP client (`ureq`), so plugins\n   * don\'t need `curl`/`wget` on PATH.\n   */\n  httpFetch(url: string, targetPath: string): ProcessHandle<SpawnResult>;\n\n  /**\n   * Wait for a process to complete and get its result (async)\n   */\n  spawnProcessWait(processId: number): Promise<SpawnResult>;\n\n  /**\n   * Get buffer text range (async, returns request_id)\n   */\n  getBufferText(bufferId: number, start: number, end: number): Promise<string>;\n\n  /**\n   * Delay/sleep (async, returns request_id)\n   */\n  delay(durationMs: number): Promise<void>;\n\n  /**\n   * Project-wide grep search (async)\n   * Searches all files in the project, respecting .gitignore.\n   * Open buffers with dirty edits are searched in-memory.\n   */\n  grepProject(pattern: string, fixedString: boolean | null, caseSensitive: boolean | null, maxResults: number | null, wholeWords: boolean | null): Promise<GrepMatch[]>;\n\n  /**\n   * Begin a streaming project-wide search and return a `SearchHandle`.\n   * The producer (host) writes matches at full speed into shared state;\n   * the consumer drains via `handle.take()` at its own cadence. Call\n   * `handle.cancel()` to abort.\n   */\n  beginSearch(pattern: string, opts?: { fixedString?: boolean; caseSensitive?: boolean; maxResults?: number; wholeWords?: boolean }): SearchHandle;\n\n  /**\n   * Replace matches in a file\'s buffer (async)\n   * Opens the file if not already in a buffer, applies edits via the buffer model,\n   * and saves. All edits are grouped as a single undo action.\n   */\n  replaceInFile(filePath: string, matches: number[][], replacement: string): Promise<ReplaceResult>;\n\n  /**\n   * Send LSP request (async, returns request_id)\n   */\n  sendLspRequest(language: string, method: string, params: Record<string, unknown> | null): Promise<unknown>;\n\n  /**\n   * Spawn a background process (async, returns request_id which is also process_id)\n   */\n  spawnBackgroundProcess(command: string, args: string[], cwd?: string): ProcessHandle<BackgroundProcessResult>;\n\n  /**\n   * Kill a background process\n   */\n  killBackgroundProcess(processId: number): boolean;\n\n  /**\n   * Create a new terminal in a split (async, returns TerminalResult)\n   */\n  createTerminal(opts?: CreateTerminalOptions): Promise<TerminalResult>;\n\n  /**\n   * Create a new editor window seeded with an agent terminal as\n   * its only buffer. Atomic \u{2014} replaces the legacy\n   * `createWindow` + `setActiveWindow` + `createTerminal`\n   * chain that left a transient `[No Name]` tab alongside the\n   * agent terminal.\n   */\n  createWindowWithTerminal(opts: CreateWindowWithTerminalOptions): Promise<SessionWithTerminalResult>;\n\n  /**\n   * Send input data to a terminal\n   */\n  sendTerminalInput(terminalId: number, data: string): boolean;\n\n  /**\n   * Close a terminal\n   */\n  closeTerminal(terminalId: number): boolean;\n\n  /**\n   * Send `signal` (\"SIGTERM\" / \"SIGKILL\" / \"SIGINT\" / \"SIGHUP\")\n   * to every process group the window `id` is tracking. The\n   * window\'s authority decides delivery; this is the\n   * canonical entry point for \"stop everything this window\n   * owns\" rather than reaching at the terminal level. Returns\n   * `false` only when the command channel is closed.\n   */\n  signalWindow(id: number, signal: string): boolean;\n\n  /**\n   * Force refresh of line display\n   */\n  refreshLines(bufferId: number): boolean;\n\n  /**\n   * Get the current locale\n   */\n  getCurrentLocale(): string;\n\n  /**\n   * Load a plugin from a file path (async)\n   */\n  loadPlugin(path: string): Promise<boolean>;\n\n  /**\n   * Unload a plugin by name (async)\n   */\n  unloadPlugin(name: string): Promise<boolean>;\n\n  /**\n   * Reload a plugin by name (async)\n   */\n  reloadPlugin(name: string): Promise<boolean>;\n\n  /**\n   * List all loaded plugins (async)\n   * Returns array of { name: string, path: string, enabled: boolean }\n   */\n  listPlugins(): Promise<Array<{name: string, path: string, enabled: boolean}>>;\n}\n";
Expand description

TypeScript EditorAPI interface (methods only)

Combine with preamble and ts-rs types to create fresh.d.ts