directlx-claude-config/plans/polished-enchanting-pretzel.md

16 KiB

hiveops-remote Implementation Plan

Overview

Create hiveops-remote at /source/hiveops-src/hiveops-remote/ with:

  • hiveops-remote-server - Java/Spring Boot control plane + module JAR hosting
  • hiveops-remote-module - Java module JAR implementing AgentModule SPI

The module JAR is downloaded from the server when the remote feature is activated, then loaded dynamically into hiveops-agent.

Requirements

  • Screen Capture: Static on-demand screenshots
  • File System: Browse directories + download files
  • License Tiers: Pro and Enterprise only
  • Distribution: Module JAR downloaded from server on activation
  • Location: /source/hiveops-src/hiveops-remote/

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        hiveops-remote                            │
├─────────────────────────────┬───────────────────────────────────┤
│   hiveops-remote-server     │      hiveops-remote-module         │
│   (Spring Boot)             │      (AgentModule JAR)             │
│                             │                                    │
│   - Control Plane API       │      Downloaded & loaded into      │
│   - Command Queue           │      hiveops-agent at runtime      │
│   - Module JAR Hosting      │                                    │
│   - Binary Result Storage   │      - Screen Capture              │
│                             │      - File Browser                │
│   PostgreSQL                │      - File Download               │
│                             │      - Result Upload               │
└─────────────────────────────┴───────────────────────────────────┘

Flow:
1. Agent checks for remote module availability
2. Downloads hiveops-remote-module.jar from server
3. ModuleLoader loads JAR via SPI
4. Module starts polling server for commands

Project Structure (Maven Multi-Module)

/source/hiveops-src/hiveops-remote/
├── pom.xml                              # Parent POM
├── hiveops-remote-server/               # Spring Boot server
│   ├── pom.xml
│   └── src/main/java/com/hiveops/remote/server/
│       ├── RemoteServerApplication.java
│       ├── config/
│       │   └── SecurityConfig.java
│       ├── controller/
│       │   ├── AgentController.java        # Agent endpoints (poll, upload)
│       │   ├── RemoteController.java       # User endpoints (commands)
│       │   └── ModuleController.java       # Module JAR download
│       ├── service/
│       │   ├── AgentService.java
│       │   ├── CommandService.java
│       │   └── BinaryService.java
│       ├── repository/
│       │   ├── AgentRepository.java
│       │   ├── CommandRepository.java
│       │   └── BinaryChunkRepository.java
│       ├── entity/
│       │   ├── RemoteAgent.java
│       │   ├── RemoteCommand.java
│       │   └── BinaryChunk.java
│       └── dto/
│           ├── AgentRegistrationRequest.java
│           ├── CommandRequest.java
│           └── ...
├── hiveops-remote-module/               # Agent module JAR
│   ├── pom.xml
│   └── src/main/java/com/hiveops/remote/module/
│       ├── RemoteModule.java              # AgentModule SPI implementation
│       ├── RemoteCommandProcessor.java    # Command polling & dispatch
│       ├── RemoteHttpClient.java          # Server communication
│       ├── screen/
│       │   ├── ScreenCaptureService.java
│       │   ├── LinuxScreenCapture.java    # X11/Wayland capture
│       │   └── WindowsScreenCapture.java  # Robot/GDI capture
│       ├── filesystem/
│       │   ├── FileSystemService.java
│       │   ├── DirectoryLister.java
│       │   ├── FileDownloader.java
│       │   └── PathValidator.java         # Security
│       └── dto/
│           ├── RemoteCommand.java
│           ├── ScreenshotParams.java
│           └── FileListParams.java
├── hiveops-remote-common/               # Shared DTOs between server & module
│   ├── pom.xml
│   └── src/main/java/com/hiveops/remote/common/
│       ├── dto/
│       │   ├── CommandType.java
│       │   ├── CommandStatus.java
│       │   ├── PollResponse.java
│       │   └── FileEntry.java
│       └── security/
│           └── PathSecurityUtils.java
└── deployments/
    ├── docker/
    │   └── Dockerfile
    └── docker-compose.yml

Module Loading Flow

1. Check for Remote Module (in hiveops-agent)

The existing hiveops-agent can be enhanced to check for downloadable modules:

// In AgentApplication or a new ModuleDownloader
public void checkRemoteModules() {
    String moduleUrl = config.get("remote.module.url");
    if (moduleUrl != null && remoteEnabled) {
        Path modulePath = downloadModule(moduleUrl, "hiveops-remote-module.jar");
        moduleLoader.loadFromPath(modulePath);
    }
}

2. Module SPI Registration

File: hiveops-remote-module/src/main/resources/META-INF/services/com.hiveops.core.module.AgentModule

com.hiveops.remote.module.RemoteModule

3. RemoteModule Implementation

public class RemoteModule implements AgentModule {
    private RemoteCommandProcessor processor;

    @Override
    public String getName() {
        return "hiveops-remote";
    }

    @Override
    public void initialize(ModuleContext context) {
        String serverUrl = context.getConfig("remote.server.url");
        String agentToken = context.getConfig("remote.agent.token");

        RemoteHttpClient client = new RemoteHttpClient(serverUrl, agentToken);
        processor = new RemoteCommandProcessor(client, context);
    }

    @Override
    public void start() {
        processor.startPolling();
    }

    @Override
    public void stop() {
        processor.stopPolling();
    }
}

Database Schema (PostgreSQL)

-- In hiveops-remote-server

CREATE TABLE remote_agents (
    id BIGSERIAL PRIMARY KEY,
    agent_id UUID UNIQUE NOT NULL DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    hostname VARCHAR(255),
    platform VARCHAR(50) NOT NULL,
    agent_version VARCHAR(50),
    module_version VARCHAR(50),
    status VARCHAR(50) NOT NULL DEFAULT 'OFFLINE',
    last_heartbeat_at TIMESTAMPTZ,
    capabilities JSONB,
    license_key VARCHAR(255),
    machine_id VARCHAR(255),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(license_key, machine_id)
);

CREATE TABLE remote_commands (
    id BIGSERIAL PRIMARY KEY,
    command_id UUID UNIQUE NOT NULL DEFAULT gen_random_uuid(),
    agent_id BIGINT NOT NULL REFERENCES remote_agents(id) ON DELETE CASCADE,
    type VARCHAR(50) NOT NULL,
    status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
    parameters JSONB,
    result JSONB,
    error_message TEXT,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    started_at TIMESTAMPTZ,
    completed_at TIMESTAMPTZ
);

CREATE TABLE binary_chunks (
    id BIGSERIAL PRIMARY KEY,
    command_id BIGINT NOT NULL REFERENCES remote_commands(id) ON DELETE CASCADE,
    chunk_index INT NOT NULL,
    total_chunks INT NOT NULL,
    data BYTEA NOT NULL,
    checksum VARCHAR(64),
    UNIQUE(command_id, chunk_index)
);

-- Module JAR versions
CREATE TABLE module_versions (
    id BIGSERIAL PRIMARY KEY,
    version VARCHAR(50) NOT NULL UNIQUE,
    filename VARCHAR(255) NOT NULL,
    checksum VARCHAR(64) NOT NULL,
    size_bytes BIGINT NOT NULL,
    released_at TIMESTAMPTZ DEFAULT NOW(),
    is_latest BOOLEAN DEFAULT FALSE
);

API Endpoints

Module Distribution

GET  /api/v1/modules/latest              - Get latest module version info
GET  /api/v1/modules/{version}/download  - Download module JAR

Agent-Facing (for hiveops-remote-module)

POST /api/v1/agents/register             - Register agent with module
GET  /api/v1/agents/poll                 - Poll for pending commands (long-poll 15s)
POST /api/v1/agents/heartbeat            - Heartbeat update
POST /api/v1/commands/{id}/status        - Update command status
POST /api/v1/commands/{id}/upload        - Upload binary result (chunked)

User-Facing

GET  /api/v1/agents                      - List registered agents
GET  /api/v1/agents/{id}                 - Get agent details
DELETE /api/v1/agents/{id}               - Unregister agent

POST /api/v1/commands/screenshot         - Request screenshot
POST /api/v1/commands/file-list          - List directory
POST /api/v1/commands/file-download      - Download file
GET  /api/v1/commands/{id}               - Get command status
GET  /api/v1/commands/{id}/result        - Download binary result

Screen Capture Implementation

Linux (X11)

public class LinuxScreenCapture {
    public byte[] capture(ScreenshotParams params) throws Exception {
        // Option 1: Use Robot (requires X11 display)
        Robot robot = new Robot();
        Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        BufferedImage image = robot.createScreenCapture(screenRect);

        // Encode as JPEG
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", baos);
        return baos.toByteArray();
    }
}

Windows

public class WindowsScreenCapture {
    public byte[] capture(ScreenshotParams params) throws Exception {
        // Same Robot API works on Windows
        Robot robot = new Robot();
        Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        BufferedImage image = robot.createScreenCapture(screenRect);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", baos);
        return baos.toByteArray();
    }
}

Note: Java's Robot class works cross-platform for basic screen capture. For headless Linux, may need Xvfb or alternative approach.


File System Service

public class FileSystemService {
    private final PathValidator pathValidator;

    public List<FileEntry> listDirectory(String path) {
        pathValidator.validate(path);  // Security check

        Path dir = Paths.get(path);
        return Files.list(dir)
            .map(p -> new FileEntry(
                p.getFileName().toString(),
                Files.isDirectory(p) ? "DIRECTORY" : "FILE",
                Files.size(p),
                Files.getLastModifiedTime(p).toInstant(),
                getPosixPermissions(p)
            ))
            .collect(Collectors.toList());
    }

    public InputStream downloadFile(String path) {
        pathValidator.validate(path);
        pathValidator.checkMaxSize(path);
        return Files.newInputStream(Paths.get(path));
    }
}

Security

  1. Agent Auth: License key + machine ID → JWT token (validated against hiveops-mgmt or standalone)
  2. Path Security: Configurable allowed paths, block .. traversal
  3. File Size Limit: Configurable max (default 100MB)
  4. Module Signature: JAR checksum verification on download

Maven Configuration

Parent pom.xml:

<groupId>com.hiveops</groupId>
<artifactId>hiveops-remote</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
    <module>hiveops-remote-common</module>
    <module>hiveops-remote-module</module>
    <module>hiveops-remote-server</module>
</modules>

<properties>
    <java.version>21</java.version>
    <spring-boot.version>3.4.1</spring-boot.version>
</properties>

hiveops-remote-module pom.xml:

<dependencies>
    <dependency>
        <groupId>com.hiveops</groupId>
        <artifactId>hiveops-core</artifactId>
        <version>3.0.1-SNAPSHOT</version>
        <scope>provided</scope>  <!-- Provided by hiveops-agent -->
    </dependency>
    <dependency>
        <groupId>com.hiveops</groupId>
        <artifactId>hiveops-remote-common</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <configuration>
                <!-- Bundle only remote-common, exclude hiveops-core -->
            </configuration>
        </plugin>
    </plugins>
</build>

Docker Deployment

docker-compose.yml:

version: '3.8'
services:
  hiveops-remote-server:
    build: .
    ports:
      - "8090:8090"
    environment:
      - DB_HOST=postgres
      - DB_NAME=hiveops_remote
    volumes:
      - ./modules:/app/modules  # Module JARs served from here
    depends_on:
      - postgres

  postgres:
    image: postgres:16-alpine
    environment:
      - POSTGRES_DB=hiveops_remote
      - POSTGRES_USER=hiveops
      - POSTGRES_PASSWORD=hiveops
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Implementation Order

Phase 1: Project Setup

  1. Create Maven multi-module project at /source/hiveops-src/hiveops-remote/
  2. Setup parent pom.xml with modules
  3. Create hiveops-remote-common with shared DTOs

Phase 2: Server (hiveops-remote-server)

  1. Create Spring Boot application
  2. Create entities and repositories
  3. Create AgentController (register, poll, upload)
  4. Create RemoteController (user commands)
  5. Create ModuleController (JAR download)
  6. Database migrations

Phase 3: Module (hiveops-remote-module)

  1. Create RemoteModule implementing AgentModule SPI
  2. Create RemoteCommandProcessor (polling loop)
  3. Implement ScreenCaptureService
  4. Implement FileSystemService + PathValidator
  5. SPI registration in META-INF/services

Phase 4: Agent Integration

  1. Add module download capability to hiveops-agent
  2. Test dynamic module loading
  3. Configuration for remote module URL

Phase 5: Docker & Testing

  1. Create Dockerfile
  2. Create docker-compose.yml
  3. End-to-end testing

Configuration

hiveops-agent hiveops.properties (to enable remote module):

# Remote module configuration
remote.enabled=true
remote.server.url=http://localhost:8090
remote.module.download.url=http://localhost:8090/api/v1/modules/latest/download
remote.license.key=${LICENSE_KEY}
remote.machine.id=${MACHINE_ID}

hiveops-remote-server application.yml:

server:
  port: 8090

spring:
  datasource:
    url: jdbc:postgresql://${DB_HOST:localhost}:5432/${DB_NAME:hiveops_remote}
    username: ${DB_USER:hiveops}
    password: ${DB_PASSWORD:hiveops}

remote:
  poll-timeout-ms: 15000
  command-timeout-ms: 300000
  module-storage-path: /app/modules

Verification

  1. Build: mvn clean package in hiveops-remote
  2. Start Server: docker-compose up -d
  3. Test Module Download:
    curl http://localhost:8090/api/v1/modules/latest
    curl -O http://localhost:8090/api/v1/modules/1.0.0/download
    
  4. Integration Test:
    • Start hiveops-agent with remote.enabled=true
    • Verify module downloads and loads
    • Request screenshot via API
    • Verify result returned