tom_d4rt_dcli 1.3.0 copy "tom_d4rt_dcli: ^1.3.0" to clipboard
tom_d4rt_dcli: ^1.3.0 copied to clipboard

Base D4rt CLI with dcli bridges. Extensible foundation for D4rt tools.

tom_d4rt_dcli #

Attribution. The tom_d4rt project is an extended clone of the original d4rt project by Moustapha Kodjo Amadou, initially published in 2025. The complete interpreter is based on his idea.

Analyzer-based D4rt CLI with dcli shell-scripting bridges — the extensible foundation for building D4rt command-line tools.

Overview #

tom_d4rt_dcli is the analyzer-based base layer of the D4rt CLI ecosystem. It sits directly on top of tom_d4rt (the Dart-analyzer-powered sandboxed interpreter) and adds:

  • Full dcli shell-scripting bridges (dcli, dcli_core, dcli_terminal)
  • VS Code scripting-API bridges (tom_vscode_scripting_api)
  • Telegram / chat integration bridges (tom_chattools)
  • An abstract base REPL class (D4rtReplBase) that downstream tool packages extend
  • A ready-to-run concrete REPL (DcliRepl) exposed as the dcli executable

The package is the shared nucleus of the stacked-REPL design used across the Tom workspace:

dcli  (DcliRepl in this package, bin/dcli.dart)
  └── tom_dartscript_bridges  (binary: d4rt — adds full Tom Framework bridges)
        └── tom_build_cli       (binary: tom — adds build/workspace bridges)

Source-based vs analyzer-free — which D4rt family #

D4rt ships in two execution families, and tom_d4rt_dcli belongs to the first:

  • Source-based (analyzer)tom_d4rt, tom_d4rt_dcli, tom_d4rt_flutter. Parses Dart source with the analyzer, giving full type inference and precise error reporting. This is the stable reference and usually the preferable choice.
  • Analyzer-free (mirror AST)tom_d4rt_ast, tom_ast_model, tom_ast_generator, tom_d4rt_exec, tom_dcli_exec, tom_d4rt_flutter_ast. Runs from pre-compiled SAstNode trees with no analyzer dependency, which makes it viable on the web (the analyzer is too large to ship there) and for on-the-fly / OTA updates. It is a complete alternative, but because generated AST bundles are large, the source-based interpreter is usually preferable unless the web/OTA constraint applies.

tom_d4rt_dcli requires the Dart analyzer (via tom_d4rt) to resolve and execute scripts. Its analyzer-free twin is tom_dcli_exec, built on tom_d4rt_exec. Both packages expose the same D4rtReplBase / DcliRepl surface and the same dcli executable — they differ only in the underlying execution engine — so a tool written against one ports to the other by swapping the dependency.


Installation #

Add to your pubspec.yaml:

dependencies:
  tom_d4rt_dcli: ^1.1.6

Or via the command line:

dart pub add tom_d4rt_dcli

dcli executable #

The package ships a bin/dcli.dart entry point. After adding the dependency you can run the REPL directly through dart run:

dart run tom_d4rt_dcli:dcli

In downstream tool packages that compile the binary, the entry point is:

import 'package:tom_d4rt_dcli/tom_d4rt_dcli.dart';

Future<void> main(List<String> arguments) async {
  await DcliRepl().run(arguments);
}

Features #

dcli shell-scripting bridges #

Scripts executed inside the REPL or passed as files have transparent access to the full dcli API family:

Package Bridge class Notable bridged types
dcli PackageDcliBridge Ask, Confirm, FetchUrl, DartScript, DartSdk, Settings, Shell, DCliPaths, FileSyncFile, NamedLock, PubCache, ProcessDetails, Remote
dcli_core PackageDcliCoreBridge Cat, Env, Find, FindItem, FindConfig, Which, DCliPlatform, LineFile, RunException
dcli_terminal PackageDcliTerminalBridge Ansi, AnsiColor, Format, Terminal, TableAlignment

Scripts can use the standard dcli idioms directly in D4rt:

import 'package:dcli/dcli.dart';

// File operations
touch('output.txt', create: true);
'output.txt'.write('Hello from D4rt!');
final lines = read('output.txt').toList();
copy('output.txt', 'backup.txt');

// Process execution
'git status'.run;
final result = 'ls -la'.toList();

// Environment
final home = env['HOME'];
if (isOnPATH('dart')) print('Dart is available');

VS Code scripting-API bridge #

The PackageTomVscodeScriptingApiBridge exposes tom_vscode_scripting_api classes to scripts running inside the interpreter, including VSCodeBridgeClient, LazyVSCodeBridgeAdapter, VSCodeBridgeResult, VSCode, VSCodeCommands, VSCodeCommonCommands, VSCodeWindow, VSCodeWorkspace, VSCodeChat, VSCodeExtensions, VSCodeLanguageModel, LanguageModelChat, LanguageModelChatMessage, ChatParticipant, ChatRequest, and related types.

Telegram / chat bridge #

The PackageTomChattoolsBridge bridges tom_chattools types — ChatConfig, ChatMessage, ChatSender, ChatAttachment, ChatResponse, ChatReceiver, ChatApi, ChatMessageFilter, and TelegramChatConfig — making them usable inside D4rt scripts without any native Dart compilation.

REPL features #

Multiline input modes — enter blocks spanning multiple lines:

Command Mode
.start-define Define functions/classes (persist in session)
.start-script Execute block with return value
.start-file Run in current REPL environment
.start-execute Run as isolated fresh program
.start-vscode-eval Evaluate in connected VS Code bridge
.start-vscode-script Execute full script in VS Code bridge
.end Finish and execute the current block

Persistent command history — history is stored to ~/.tom/dcli/.history (up to 500 lines) and reloaded on the next REPL startup. Arrow-key navigation is provided by dart_console.

Sessions — all interactive input is recorded to ~/.tom/dcli/<session-id>.session.txt and replayed on resume:

dcli -session mywork        # start or resume a named session
dcli -replace-session mywork  # delete session and start fresh
dcli -list-sessions           # list available sessions

Replay files — pre-written .dcli (or .replay.txt) files can be loaded interactively or executed headlessly:

dcli setup.dcli                          # execute replay file and exit
dcli -run-replay setup.dcli              # same, explicit flag
dcli -run-replay tests.dcli -test        # test mode (verifies assertions)
dcli -replay warmup.dcli -session main   # replay into a named session
dcli -replay warmup.dcli                 # replay before starting REPL

Bot mode — run the REPL as a Telegram bot server. Commands are received from authorised Telegram users, executed against the D4rt interpreter, and results are returned as formatted messages:

dcli --bot-mode --bot-config bot.yaml

Bot-mode configuration (BotModeConfig) is loaded from a YAML file and supports multiple bots, per-bot VS Code server connections, command whitelists/blacklists, directory allow/block lists, execution time/output-size limits, file-transfer policies, and Telegram message formatting options.

stdin execution — pipe code directly:

echo 'print(42);' | dcli --stdin
cat my_script.dart | dcli --stdin
echo 'return 5 + 6;' | dcli --stdin   # exit code = result

Init source — place a dcli_init_source.dart file in ~/.tom/dcli/ to auto-import packages or declare globals before every session.

Command aliases (defines) — create shorthand aliases with argument placeholders:

define greet=print("Hello, $1!");
@greet World    # → prints Hello, World!

Keyboard shortcutsUp/Down history, Home/Ctrl-A, End/Ctrl-E, Ctrl-U, Ctrl-K, Ctrl-L, Ctrl-C (cancel async / exit on second press).


Quick Start #

Running the REPL interactively #

dart run tom_d4rt_dcli:dcli

The banner shows the tool version. Type help for the full command reference.

Evaluating a single expression #

dart run tom_d4rt_dcli:dcli "DateTime.now()"
dart run tom_d4rt_dcli:dcli "env['HOME']"

Executing a Dart file #

dart run tom_d4rt_dcli:dcli myscript.dart

Running a replay file #

dart run tom_d4rt_dcli:dcli my_setup.dcli

Shebang scripts — run .dart files like shell scripts #

Once the dcli binary is on your PATH (compiled from a downstream tool, or via dart pub global activate), a D4rt script can carry a shebang and run directly:

#!/usr/bin/env dcli
import 'package:dcli/dcli.dart';

// A throwaway maintenance script — no compile step needed.
final stale = find('*.tmp', workingDirectory: '.').toList();
for (final f in stale) {
  print('removing $f');
  delete(f);
}
print('cleaned ${stale.length} temp files');
chmod +x cleanup.dart
./cleanup.dart          # the shebang routes the file through dcli

Piping scripts via stdin #

For one-liners, generated code, or composing with other shell tools, pipe the source straight into dcli --stdin. The process exit code is the script's return value, so scripts compose into pipelines and && chains:

echo 'print(42);' | dcli --stdin
cat my_script.dart | dcli --stdin
echo 'return 5 + 6;' | dcli --stdin          # exit code = 11
generate_script | dcli --stdin && echo ok    # gate on the script's result

Extending D4rtReplBase to build your own CLI tool #

D4rtReplBase is the abstract backbone. Subclass it and override the extension points:

import 'package:tom_d4rt/tom_d4rt.dart';
import 'package:tom_d4rt_dcli/tom_d4rt_dcli.dart';

class MyToolRepl extends D4rtReplBase {
  @override
  String get toolName => 'MyTool';

  @override
  String get toolVersion => '1.0.0';

  /// Called once at startup — register every bridge the tool needs.
  @override
  void registerBridges(D4rt d4rt) {
    // Register the base dcli bridges provided by this package:
    TomD4rtDcliBridge.register(d4rt);
    // Add your own bridges here...
  }

  /// Return the import block prepended to every script.
  @override
  String getImportBlock() {
    return getStdlibImports() + TomD4rtDcliBridge.getImportBlock();
  }

  /// Describe available bridges in the `help` output.
  @override
  String getBridgesHelp([D4rt? d4rt]) => 'Bridges: dcli, my_custom_package';

  /// Handle tool-specific REPL commands.
  /// Return true to consume the command, false to fall through.
  @override
  Future<bool> handleAdditionalCommands(
    D4rt d4rt,
    ReplState state,
    String line, {
    bool silent = false,
  }) async {
    if (line == 'my-command') {
      print('Handled by MyTool!');
      return true;
    }
    return false;
  }
}

Future<void> main(List<String> arguments) async {
  await MyToolRepl().run(arguments);
}

To also include VS Code integration, mix in VSCodeIntegrationMixin (as DcliRepl itself does) and call initVSCodeIntegration() inside createReplState, then delegate to handleVSCodeCommands from handleAdditionalCommands.

Using the cli global variable inside scripts #

Every D4rt session exposes a cli global (type D4rtCliApi) that gives scripts programmatic access to REPL operations:

// Inside a D4rt script or replay file
cli.cd('/my/project');
await cli.replay('setup.dcli');

final allClasses = cli.classes();
for (final c in allClasses) {
  print('${c.name}: ${c.methods.length} methods');
}

final result = await cli.eval('1 + 2');
print(result); // 3

Examples #

The example/ folder is the canonical DCli sample home for the D4rt CLI ecosystem. Alongside the single-file snippets it ships two extended, multi-file CLI applications:

Sample Description
example/build_suite/ Build/automation tool — BuildTask hierarchy + TaskRunner across files, shell bridges, and a buildkit.yaml BuildKit pipeline
example/log_pipeline/ File-processing pipeline — parse → filter → aggregate stages over generated .log files, with a written report and coloured summary

Both run unchanged on the analyzer-free sibling tom_dcli_exec, which points back here instead of duplicating samples.

For a standalone, repo-curated walkthrough see the d4rt_dcli_sample in the shared tom_d4rt_samples collection — a self-contained DCli scripting tour sitting alongside the interpreter, Flutter, and advanced samples.


Architecture #

Stacked-REPL design #

D4rtReplBase  (abstract base — this package)
    │
    ├─ DcliRepl + VSCodeIntegrationMixin  (concrete dcli REPL — this package)
    │
    └─ [downstream tool packages extend D4rtReplBase directly]
         e.g. tom_dartscript_bridges (d4rt binary),
              tom_build_cli (tom binary)

D4rtReplBase owns the full REPL loop, argument parsing, session management, history, multiline input, bot mode, stdin mode, --help/--version output, and the cli global registration. Downstream tools add only bridges, additional commands, and branding.

Bridge registration #

Bridges are generated by tom_d4rt_generator (dev dependency ^1.9.0) via build_runner. The generation marker is tracked in lib/d4rt_bridges.g.info. The generated bridge modules registered by TomD4rtDcliBridge.register(d4rt) are:

Module Bridged package
PackageDcliBridge dcli
PackageDcliCoreBridge dcli_core
PackageDcliTerminalBridge dcli_terminal
PackageTomVscodeScriptingApiBridge tom_vscode_scripting_api
PackageTomChattoolsBridge tom_chattools
PackageCryptoBridge crypto
PackageTomD4rtDcliBridge tom_d4rt_dcli itself (the cli API)

Total bridged classes across all modules: 70 (as of v1.1.4 build 2026-02-07).

Data directory layout #

The REPL stores all persistent state under ~/.tom/dcli/:

~/.tom/dcli/
├── .history                      # Persistent command history (up to 500 lines)
├── dcli_init_source.dart         # Optional custom init script (auto-loaded)
├── <session-id>.session.txt      # Recorded session files (auto-managed)

Ecosystem fit #

Package Role Notes
tom_d4rt Analyzer-based interpreter runtime Direct dependency
tom_d4rt_dcli This package — dcli CLI base Analyzer-based
tom_dcli_exec Analyzer-free dcli CLI base Lighter weight, no analyzer
tom_dartscript_bridges Full D4rt binary (d4rt) Extends D4rtReplBase
tom_build_cli Tom workspace CLI (tom) Extends D4rtReplBase
tom_d4rt_generator Bridge code generator Dev dependency
tom_vscode_scripting_api VS Code bridge API Runtime dependency
tom_chattools Telegram / chat API Runtime dependency

All packages live in the tom_d4rt monorepo at github.com/al-the-bear/tom_d4rt. This package resides at tom_ai/d4rt/tom_d4rt_dcli.


Further documentation #

Document What it covers
doc/build.md Building and compiling the dcli binary; bridge regeneration via build_runner.
doc/testing.md Test layout and how to run the suite with testkit.
doc/tom_d4rt_dcli_limitations.md Known limitations of the dcli REPL and its bridges.
Package Relationship
tom_d4rt The source-based interpreter this package is built on.
tom_dcli_exec Analyzer-free twin — same DcliRepl surface on tom_d4rt_exec.
tom_d4rt_generator Generates the dcli bridges (*.b.dart).

Status #

Current version: 1.1.6 — duplicate-export collision fixes for AOT-compiled hosted consumers (see CHANGELOG); bridges regenerated against tom_d4rt_generator 1.9.0.

Requires Dart SDK ^3.10.4.

tom_d4rt:                ^1.8.20
tom_vscode_scripting_api: ^1.0.1
tom_chattools:            ^1.0.2
dcli:                    ^8.4.2
dcli_core:               ^8.2.8
dcli_terminal:           ^8.4.2

License #

BSD 3-Clause. See LICENSE.