← Vscode
Publishedrole: extensionlicense: BSD-3-Clause

tom_vscode_scripting_api

tom_vscode_scripting_api · v1.1.0

The typed, bridge-agnostic Dart client for the Tom AI extension's CLI Integration Server. Over one local socket it mirrors three API families — VS Code itself (`window`, `workspace`, `commands`, `lm`, …), the Anthropic Agent SDK, and the extension's own features — so scripts drive a running window from plain Dart.

View repository → See License
Status
Published
LOC
8.0k
Tests
85
Test LOC
1.6k

Overview

`tom_vscode_scripting_api` is the Dart API surface that editor scripts target. It defines an abstract adapter contract plus typed namespaces over VS Code's Window, Workspace, Commands, Extensions, Language Model, and Chat APIs, with convenient top-level accessors like `window`, `workspace`, and `commands`. The interface is bridge-agnostic: the same script code runs against any adapter. A bundled socket-based, JSON-RPC client connects to the extension host, and an adapter wires the typed namespaces onto that transport. It is the scripting layer over the bridge runtime. Where `tom_vscode_bridge` provides the executing server, this package gives framework authors the clean, typed Dart surface to write VS Code automation against.

What it enables

Enables Typed VS Code scripting in Dart, Anthropic Agent SDK from Dart, Extension-feature automation.

Relationships

Standalone — no declared relationships.

tom_vscode_scripting_api

> Tom VS Code — part of the Tom Framework by Peter Nicolai Alexis Kyaw. > Licensed BSD-3-Clause. See LICENSE.

Drive a running VS Code window from Dart. A typed, bridge-agnostic client for the Tom AI VS Code extension: open files, run commands, query the language model, stream an Anthropic Agent SDK session, and reach the extension's own features — all over a local socket, from a plain Dart program or a *.d4rt.dart script.

---

Overview

The Tom AI extension hosts a CLI Integration Server: a JSON-RPC server that exposes the editor's capabilities to out-of-process clients. tom_vscode_scripting_api is the Dart client for that server. Anything the extension can do inside the editor host becomes a typed Dart call.

It exposes three families of API behind one connection:

1. VS Code scripting — the editor mirrored as Dart (window, workspace, commands, extensions, lm, chat) plus the batteries-included VsCodeHelper. 2. Anthropic Agent SDK — a 1:1 Dart mirror of the Agent SDK: streaming query(), in-process Dart tools, and a canUseTool permission callback. 3. Extension features — the Tom AI extension's own subsystems (todos, the prompt queue, timed requests, documents, workspace metadata, tools, send-to-chat) as static-method classes.

The package is standalone (zero runtime dependencies) and bridge-agnostic: every API talks to an abstract VSCodeAdapter, so the same surface is testable against fakes.

---

Installation

# pubspec.yaml
dependencies:
  tom_vscode_scripting_api: ^1.1.0
dart pub add tom_vscode_scripting_api

No native dependencies; pure Dart, SDK ^3.10.4.

---

Features

VS Code scripting

APIWhat it does
VSCode Root singleton — version, env, clipboard, external URIs; owns the namespaces.
window (VSCodeWindow) Messages, quick picks, input boxes, editors, output channels, status bar, terminals, file dialogs.
workspace (VSCodeWorkspace) Folders, file finding, documents, host-side file system, configuration.
commands (VSCodeCommands) Execute/register commands; VSCodeCommonCommands named constants.
extensions (VSCodeExtensions) Query, activate, and read exports of installed extensions.
lm (VSCodeLanguageModel) Select chat models (Copilot et al.), send requests, count tokens, register/invoke LM tools.
chat (VSCodeChat) Register a chat participant whose handler runs in your Dart process.
VsCodeHelper All-static convenience layer — Dart/Flutter tooling, Copilot prompts, editor edits, VsProgress , FileBatch .

Anthropic Agent SDK

APIWhat it does
AgentSdkClient query() → streaming AgentQuery ; collectQuery()List<SdkMessage> .
Options Full Agent SDK option surface (model, tools, maxTurns , permissionMode , sessions, sub-agents, thinking…).
SdkMessage (sealed) Raw-preserving typed message stream ( SdkAssistantMessage , SdkResultMessage , …).
SdkMcpTool / McpSdkServerConfig In-process Dart tools the agent can call.
canUseTool / PermissionResult Per-call permission callback running in your process.

Extension features

APIWhat it does
AiPromptApi Run a prompt through the configured local LLM; manage profiles and models.
AiConversationApiDrive the multi-turn bot-conversation engine.
TomTodoApiCRUD over quest / workspace / session todos.
TomQueueApiFull control of the multi-transport prompt queue.
TomTimedApi Create and manage scheduled prompts; control the timer engine.
TomDocumentApiGeneric document store + typed Tom-folder accessors.
TomWorkspaceApi Workspace info, projects, quests, the active quest, chat variables.
TomToolsApi Invoke registered tools; fetch tools JSON for prompt injection.
TomChatApi Send a prompt to the active chat target (Anthropic or Copilot).

Bridge transport

TypeWhat it does
VSCodeAdapter Abstract contract — sendRequest(method, params). Everything routes through it.
VSCodeBridgeClient Owns the socket; JSON-RPC 2.0, length-prefixed TCP, notifications + callbacks.
VSCodeBridgeAdapter Wraps a connected client as a VSCodeAdapter.
LazyVSCodeBridgeAdapter Same, but connects on first use — ideal for scripts.
connectToWorkspace / findBridgePortForWorkspace / scanBridgePorts Discovery helpers — resolve the right window by the workspace it has open.

---

Quick start

First, in the target VS Code window, run "DS: Start Tom CLI Integration Server" (Command Palette). Then, from Dart:

import 'package:tom_vscode_scripting_api/tom_vscode_scripting_api.dart';

Future<void> main() async {
  // Resolve the window by the workspace it has open, connect, and promote the
  // adapter to the VSCode singleton.
  await connectToWorkspace('tom_agent_container', initializeVSCode: true);

  final version = await VSCode.instance.getVersion();
  await VSCode.instance.window.showInformationMessage('Connected to VS Code $version');
  print('VS Code version: $version'); // e.g. VS Code version: 1.99.0
}

---

Example projects

Runnable, self-contained samples live under example/, ordered as a learning path — each introduces one new capability on top of the last. Each sample is its own Dart subproject with a comprehensive README.

SampleIntroduces
vscode_scripting_introduction_sample Connecting to a live window — messages, commands, workspace folders, reading and opening files. Start here.
vscode_scripting_advanced_sample Editor edits, file batches, progress and pickers, the language model, and VsCodeHelper.
vscode_agent_tools_sample The extension's own feature APIs — todos, the prompt queue, timed requests, documents, workspace metadata, tools, send-to-chat.
vscode_agent_sdk_sample Streaming an Anthropic Agent SDK query() with Options , typed messages, in-process Dart tool() s, and canUseTool .

---

Usage

Connect

There are two ways to connect; pick by how many windows you run.

By port (single window):

import 'package:tom_vscode_scripting_api/script_globals.dart';

final adapter = LazyVSCodeBridgeAdapter(host: '127.0.0.1', port: 19900);
VSCode.initialize(adapter);

By workspace name (recommended for multi-window): the discovery helper scans the port range and matches the window by its open workspace.

final adapter = await connectToWorkspace('tom_agent_container', initializeVSCode: true);

Two initialisation styles

Know which an API uses:

  • VS Code-namespace classes (VSCode, window, workspace, commands,

extensions, lm, chat) read the VSCode singleton — call VSCode.initialize(adapter) once. - Extension-feature classes (TomTodoApi, TomQueueApi, AiPromptApi, …) are static-method classes — each needs <Class>.setAdapter(adapter).

final adapter = await connectToWorkspace('tom_agent_container');
VSCode.initialize(adapter);        // enables vscode / window / workspace / ...
TomTodoApi.setAdapter(adapter);    // enables TomTodoApi.*
TomQueueApi.setAdapter(adapter);   // enables TomQueueApi.*

Script the editor

await window.setStatusBarMessage('Running analyzer…');
await commands.executeCommand('workbench.action.files.saveAll');

final diagnostics = await VsCodeHelper.getDiagnostics('lib/main.dart');
if (diagnostics.isEmpty) {
  await window.showInformationMessage('No problems found');
} else {
  await window.showWarningMessage('${diagnostics.length} problems');
}

VS Code scripting guide

Run an agent

final bridge = VSCodeBridgeClient(host: '127.0.0.1', port: 19900);
await bridge.connect();
final client = AgentSdkClient(VSCodeBridgeAgentSdkTransport(bridge));

final query = client.query(
  prompt: 'Read lib/parser.dart and suggest three improvements',
  options: Options(model: 'claude-sonnet-4', maxTurns: 10),
);

await for (final m in query) {
  if (m is SdkAssistantMessage) {
    for (final b in m.content) {
      if (b is TextBlock) stdout.write(b.text);
    }
  }
}

The Agent SDK transport needs the raw VSCodeBridgeClient (not just the adapter) because it uses the bidirectional notification + callback channel. → Agent SDK guide

Drive the extension's features

TomWorkspaceApi.setAdapter(adapter);
TomTodoApi.setAdapter(adapter);
TomChatApi.setAdapter(adapter);

await TomWorkspaceApi.setActiveQuest('vscode_extension');
final todos = await TomTodoApi.listQuestTodos('vscode_extension');

final reply = await TomChatApi.sendToChat(
  'I have ${todos.length} open todos. Suggest which to tackle first.',
);
print(reply.text);

Extension scripting guide

---

Architecture

Three layers, lowest to highest. Everything above the adapter contract ultimately calls sendRequest; swap the adapter and the whole surface targets a different transport (or a test double).

┌───────────────────────────────────────────────────────────────┐
│  3. High-level APIs                                            │
│     VSCode / window / workspace / commands / extensions / lm   │
│     / chat   ·   VsCodeHelper   ·   AgentSdkClient             │
│     Ai*/Tom* extension-feature APIs                            │
├───────────────────────────────────────────────────────────────┤
│  2. Transport                                                 │
│     VSCodeBridgeAdapter / LazyVSCodeBridgeAdapter             │
│     VSCodeBridgeClient  (JSON-RPC 2.0, length-prefixed TCP)   │
├───────────────────────────────────────────────────────────────┤
│  1. Adapter contract                                          │
│     abstract VSCodeAdapter.sendRequest(method, params)        │
└───────────────────────────────────────────────────────────────┘
                              │  TCP socket  (port 19900–19909)
                              ▼
┌───────────────────────────────────────────────────────────────┐
│  Tom AI VS Code extension  —  CLI Integration Server          │
│  executes JS in the extension host (context.vscode global),   │
│  routes <area>.<op>Vce methods to extension features          │
└───────────────────────────────────────────────────────────────┘

VS Code-namespace calls are sent as an executeScriptVce request whose payload is JavaScript run in the extension host with a context.vscode global; the extension-feature APIs instead call dedicated <area>.<op>Vce methods (e.g. queue.listVce, localLlm.processVce). Server→client callbacks (Agent SDK chunks, canUseTool, chat handlers) are JSON-RPC requests pushed back over the same socket and routed by BridgeRequestDispatcher.

Key types

TypeRole
VSCodeAdapter Abstract request/response contract — the single seam every API depends on.
VSCodeBridgeClient Socket owner: connect / disconnect , sendRequest , notifications stream, server→client handler registration.
VSCodeBridgeAdapter / LazyVSCodeBridgeAdapter Adapt a client to VSCodeAdapter; the lazy variant connects on first use.
VSCode Root singleton; gateway to the namespace classes after initialize.
VsCodeHelperStatic convenience layer over the namespaces.
AgentSdkClient / AgentQuery Agent SDK entry; AgentQuery extends StreamView<SdkMessage> and adds interrupt() .
AgentSdkTransport / VSCodeBridgeAgentSdkTransport Agent SDK seam and its socket-backed production implementation.
OptionsAgent SDK configuration data class.
SdkMessage / ContentBlock Sealed, raw-preserving message and content hierarchies.
BridgeRequestDispatcher Routes server→client JSON-RPC requests to registered handlers.
Tom*Api / Ai*Api Static-method extension-feature classes (each set up with setAdapter).

---

Ecosystem

tom_vscode_scripting_api is the Dart client half of the Tom VS Code repo. The two halves meet only at the extension's JSON-RPC CLI Integration Server.

        ┌──────────────── inside the editor (TypeScript) ────────────────┐
        │  tom_vscode_extension  ◄── tom_vscode_shared / tom_vscode_workflow │
        │   · chat panels · prompt queue · tool registry · MCP server     │
        │   · CLI Integration Server  (JSON-RPC over TCP 19900–19909)     │
        └───────────────────────────────▲────────────────────────────────┘
                                         │  local socket
        ┌────────────────────── driving it (Dart) ───────────────────────┐
        │  tom_vscode_scripting_api  ──►  THIS PACKAGE (typed client)      │
        │  tom_vscode_bridge         ──►  Dart bridge server for CLI/d4rt  │
        └─────────────────────────────────────────────────────────────────┘

that hosts the CLI Integration Server this client talks to. - tom_vscode_bridge — the Dart bridge server that builds on this package to give Tom CLI tools and d4rt scripts editor access. - Repository map — the whole Tom VS Code ecosystem at a glance.

---

Further documentation

The full user guides live in doc/:

GuideCovers
vscode_api_intro.md Overview, architecture, connection model — start here.
vscode_api_vscode_scripting_guide.md Scripting VS Code itself + VsCodeHelper.
vscode_api_anthropic_agent_sdk_guide.md Scripting the Anthropic Agent SDK.
vscode_api_extension_scripting_guide.md Scripting the extension's own features.

---

Status

Version1.1.0
Dart SDK^3.10.4
Runtime dependenciesnone (standalone)
Tests85 passing across 8 suites (dart test)
LicenseBSD-3-Clause

---

License

Part of the Tom Framework by Peter Nicolai Alexis Kyaw, BSD-3-Clause. See LICENSE. </content> </invoke>

License
BSD 3-Clause License

Copyright (c) 2024-2026, Peter Nicolai Alexis Kyaw
Find me on LinkedIn under Alexis Kyaw
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.