npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@loopstack/remote-client

v0.26.2

Published

Remote client and tools for Loopstack workflows — HTTP client for communicating with remote server processes, plus workflow tools for file operations, command execution, and environment management

Readme


title: Remote Client Module description: HTTP client and workflow tools for Loopstack remote servers — RemoteClientModule, RemoteClient service, EnvironmentService, ReadTool, WriteTool, EditTool, BashTool, GlobTool, GrepTool, RebuildAppTool, ResetWorkspaceTool, LogsTool, SyncSecretsTool, file operations, shell commands, environment management on remote workspaces

@loopstack/remote-client

Remote environment module for the Loopstack automation framework.

HTTP client and workflow tools for communicating with a Loopstack remote server — the sandboxed process that owns a workspace's filesystem and shell. This module provides the foundation that other feature modules (git, code-agent, file-explorer) build on top of.

When to Use

  • You need to read, write, or edit files on a remote workspace from within a workflow
  • You need to execute shell commands on a remote instance
  • You need to manage application lifecycle (rebuild, reset, logs) on a remote environment
  • You are building a module that needs low-level access to the remote server API — inject RemoteClient directly

Installation

npm install @loopstack/remote-client

Register the module with forRoot():

import { RemoteClientModule } from '@loopstack/remote-client';

@Module({
  imports: [RemoteClientModule.forRoot()],
})
export class AppModule {}

RemoteClientModule.forRoot() registers globally and depends on SecretsModule and TypeORM entities (WorkspaceEntity, WorkspaceEnvironmentEntity).

Quick Start

Inject tools directly into your workflow via the constructor — they are NestJS providers resolved by their @Tool({ name }) value through DI:

import { BaseWorkflow, Transition, Workflow } from '@loopstack/common';
import { BashTool, EditTool, ReadTool } from '@loopstack/remote-client';

@Workflow({ widget: './my.ui.yaml' })
export class MyWorkflow extends BaseWorkflow {
  constructor(
    private readonly read: ReadTool,
    private readonly edit: EditTool,
    private readonly bash: BashTool,
  ) {
    super();
  }

  @Transition({ from: 'ready', to: 'done' })
  async bumpVersion(state: unknown, ctx: RunContext) {
    const { data } = await this.read.call({ file_path: 'package.json' });

    await this.edit.call({
      file_path: 'package.json',
      old_string: '"version": "0.1.0"',
      new_string: '"version": "0.2.0"',
    });

    await this.bash.call({ command: 'npm install' });
  }
}

Every tool automatically resolves the remote agent URL from the current execution scope — you never pass connection details manually.

How It Works

A Loopstack workspace runs inside a remote server (container, VM, or local process) that exposes an HTTP API for file operations, shell commands, and environment management.

Workflow / Tool
      |
      v
  EnvironmentService  -->  resolves agent URL from execution scope
      |
      v
  RemoteClient        -->  typed HTTP client (fetch-based)
      |
      v
  Remote Server       -->  /files/*, /exec, /app/*, /git/*

EnvironmentService resolves the correct remote agent URL for the current workflow execution. It caches environments per execution scope and prefers the sandbox slot by default.

RemoteClient is a plain @Injectable() service that wraps all HTTP calls to the remote server. It handles file operations, shell execution, app lifecycle, and git operations. You can inject it directly for advanced use cases.

Using RemoteClient directly

For cases where tools are not sufficient, inject RemoteClient and EnvironmentService:

import { Injectable } from '@nestjs/common';
import { EnvironmentService, RemoteClient } from '@loopstack/remote-client';

@Injectable()
export class MyService {
  constructor(
    private readonly client: RemoteClient,
    private readonly env: EnvironmentService,
  ) {}

  async listFiles(path: string): Promise<string[]> {
    const url = await this.env.getAgentUrl();
    const result = await this.client.glob(url, `${path}/**/*`);
    return result.files;
  }
}

forFeature() — Registering environment slots

Use RemoteClientModule.forFeature() to register environment slot configurations from other modules:

RemoteClientModule.forFeature({
  slots: [{ id: 'sandbox', label: 'Sandbox', type: 'fly' }],
});

Tools Reference

All tools resolve the remote agent URL automatically from the execution scope.

File Operations

read

Reads a file from a remote instance. Returns file content. Supports offset and limit for reading specific line ranges.

| Arg | Type | Required | Description | | ----------- | -------- | -------- | --------------------------------------------- | | file_path | string | Yes | The file path to read | | offset | number | No | Line number to start reading from (1-indexed) | | limit | number | No | Number of lines to read |

Returns: { content: string, path: string }

write

Writes a file to a remote instance. Creates parent directories if needed. Overwrites existing files.

| Arg | Type | Required | Description | | ----------- | -------- | -------- | -------------------------------- | | file_path | string | Yes | The file path to write | | content | string | Yes | The content to write to the file |

Returns: { success: boolean, path: string }

edit

Performs exact string replacement in a file on a remote instance. Fails if old_string is not unique unless replace_all is true.

| Arg | Type | Required | Description | | ------------- | --------- | -------- | ---------------------------------------- | | file_path | string | Yes | The file path to edit | | old_string | string | Yes | The exact string to find and replace | | new_string | string | Yes | The replacement string | | replace_all | boolean | No | Replace all occurrences (default: false) |

Returns: { success: boolean, path: string, replacements: number }

Search

glob

Finds files by glob pattern on a remote instance. Returns relative file paths.

| Arg | Type | Required | Description | | --------- | -------- | -------- | -------------------------------------------------- | | pattern | string | Yes | Glob pattern to match files (e.g. **/*.ts) | | path | string | No | Directory to search in, relative to workspace root |

Returns: { files: string[] }

grep

Searches file contents by regex pattern on a remote instance. Returns matching lines with file paths and line numbers.

| Arg | Type | Required | Description | | ------------------ | --------- | -------- | -------------------------------------------------- | | pattern | string | Yes | Regex pattern to search for in file contents | | path | string | No | Directory to search in, relative to workspace root | | glob | string | No | Glob pattern to filter files (e.g. *.ts) | | type | string | No | File type filter (e.g. js, ts, py) | | case_insensitive | boolean | No | Case-insensitive search |

Returns: { matches: { file: string, line: number, content: string }[] }

Shell

bash

Executes a shell command on a remote instance. Returns stdout, stderr, and exit code.

| Arg | Type | Required | Description | | --------- | -------- | -------- | ---------------------------- | | command | string | Yes | The shell command to execute | | timeout | number | No | Timeout in milliseconds |

Returns: { stdout: string, stderr: string, exitCode: number }

App Lifecycle

rebuild_app

Rebuilds and restarts the app on a remote instance. Takes no arguments.

Returns: { success: boolean, message: string }

reset_workspace

Resets the workspace to its initial state, clearing all changes, temp files, database, and Redis. Takes no arguments.

Returns: { success: boolean, message: string }

logs

Retrieves application logs from the remote instance. Returns stdout and/or stderr output from the running application.

| Arg | Type | Required | Description | | ------- | --------------------------- | -------- | ------------------------------------------------------------ | | lines | number | No | Number of recent log lines to return (default 100, max 5000) | | type | "out" \| "error" \| "all" | No | Which logs to retrieve (default "all") |

Returns: { stdout: string, stderr: string }

Secrets

sync_secrets

Syncs all workspace secrets to the remote environment as .env variables and restarts the app. Call this before or during app restart to ensure secrets (API keys, config values) are available.

Takes no arguments.

Returns: { success: boolean, count: number } or { success: true, count: 0, message: string } when no secrets exist.

Configuration

forRoot() options

RemoteClientModule.forRoot({
  environments: {
    available: [{ type: 'fly', label: 'Fly.io Machine' }],
  },
});

| Option | Type | Description | | ------------------------ | --------------------------------- | ------------------------------------------------------- | | environments.available | AvailableEnvironmentInterface[] | List of available environment types users can provision |

Public API

  • Module: RemoteClientModule
  • Services: RemoteClient, EnvironmentService, EnvironmentConfigService
  • Controller: EnvironmentController
  • Tools: ReadTool, WriteTool, EditTool, BashTool, GlobTool, GrepTool, RebuildAppTool, ResetWorkspaceTool, LogsTool, SyncSecretsTool
  • Entities: WorkspaceEnvironmentEntity
  • DTOs: WorkspaceEnvironmentContextDto, WorkspaceEnvironmentDto
  • Types: RemoteClientModuleOptions, RemoteClientFeatureOptions, BashArgs, BashResult, EditArgs, EditResult, GlobArgs, GlobResult, GrepArgs, GrepResult, LogsArgs, LogsResult, ReadArgs, ReadResult, RebuildAppResult, ResetWorkspaceResult, SyncSecretsResult, WriteArgs, WriteResult, FileReadResponse, FileEditResponse, ExecResponse, GlobResponse, GrepMatch, GrepResponse

Dependencies

  • @loopstack/common — framework utilities, BaseTool, @Tool, @Transition, EXECUTION_SCOPE
  • @loopstack/secrets-module — consumed by SyncSecretsTool to read workspace secrets
  • @nestjs/common, @nestjs/core — NestJS framework and DiscoveryModule
  • @nestjs/typeorm, typeorm — workspace and environment entity persistence
  • zod — tool argument schema validation

Related

About

Author: Jakob Klippel

License: MIT