How INFINI Console Developer Tools Handles Workspace Management and Command Persistence

INFINI Console's Developer Tools module persists workspaces as Layout documents with type "workspace" via the Layout API, while storing reusable commands as CommonCommand documents in a dedicated Elasticsearch index, both exposed through RESTful endpoints with fine-grained permission controls.

The infinilabs/console repository provides a comprehensive web interface for Elasticsearch operations, with the Developer Tools (DevTools) module enabling users to write, execute, and save queries. This article examines the dual-persistence architecture that powers workspace management and command storage, referencing the actual Go source files and React front-end components that implement these features.

Workspace Management Through the Layout API

The Developer Tools module treats user workspaces as specialized dashboard layouts, leveraging a generic layout management system with a specific type discriminator.

The Workspace Data Model

In model/layout.go, the system defines a constant that identifies workspace layouts:

const (
    LayoutTypeWorkspace = "workspace"
)

This constant appears at lines 49-51, distinguishing workspace layouts from other dashboard types. When a user creates a new workspace through the DevTools UI, the front-end sends a POST /layout request to the server. The handler creates a new model.Layout record, populates the Creator and Created fields, and explicitly sets Type = LayoutTypeWorkspace before persistence.

CRUD Operations and Endpoint Registration

The Layout API implements full CRUD functionality in plugin/api/layout/layout.go. Route registration occurs in plugin/api/layout/api.go (lines 41-46), where HTTP verbs bind to handler functions:

// Endpoints include:
// POST   /layout          - Create workspace
// GET    /layout/:id      - Retrieve workspace
// PUT    /layout/:id      - Update workspace
// DELETE /layout/:id      - Remove workspace

These handlers utilize the generic ORM helpers—orm.Get, orm.Search, orm.Update, and orm.Delete—to interact with the underlying Elasticsearch storage. Each operation validates permissions against the PermissionLayoutRead and PermissionLayoutWrite constants defined in core/security/enum/const.go.

Index Registration and Storage

The workspace data persists in the layout index, registered during application startup in main.go at line 156. The registration binds the model.Layout struct to the Elasticsearch index, enabling the ORM layer to handle document serialization and query generation automatically.

Command Persistence in Elasticsearch

While workspaces manage UI layouts, the command persistence layer handles the storage and retrieval of reusable Elasticsearch queries.

The CommonCommand Document Structure

Commands are stored as CommonCommand documents, defined in the shared framework package (infini.sh/framework/core/elastic.CommonCommand). The system registers this schema with a custom index name in main.go at line 146:

orm.RegisterSchemaWithIndexName(elastic.CommonCommand{}, "commands")

This registration ensures all command documents route to the dedicated commands index, separate from the workspace layout storage.

Command Lifecycle API Handlers

The file plugin/api/index_management/common_command.go implements four primary handlers that manage the command lifecycle:

HandleAddCommonCommandAction (lines 40-81) processes POST /elasticsearch/command requests. The handler generates a UUID, timestamps the command, validates against duplicate titles, and indexes the document using esClient.Index.

HandleSaveCommonCommandAction (lines 86-127) handles PUT /elasticsearch/command/:cid. This endpoint overwrites existing documents by ID, preserving the command ID while updating the query content and metadata.

HandleQueryCommonCommandAction constructs a query DSL for GET /elasticsearch/command, returning the raw Elasticsearch search response with all saved commands for the current user context.

HandleDeleteCommonCommandAction (lines 130-150) executes DELETE /elasticsearch/command/:cid, removing the document from the index and invalidating the in-memory cache entry simultaneously.

Security and Access Control

Route registration in plugin/api/init.go (lines 65-68) binds these handlers to specific permission constants:

// Permission checks enforced:
// - PermissionCommandRead  (for GET operations)
// - PermissionCommandWrite (for POST/PUT/DELETE operations)

These permissions, defined in core/security/enum/const.go, ensure that only authorized users can modify the shared command repository while allowing broader read access for team collaboration.

Front-End Integration and Developer Experience

The React-based front-end bridges user interactions with these back-end services through dedicated service layers and UI components.

DevTools Settings Management

Editor preferences and DevTools configuration reside in web/src/components/vendor/console/services/settings.ts. The DevToolsSettings interface (lines 22-30) defines:

interface DevToolsSettings {
  fontSize: number;
  autocomplete: boolean;
  lineNumbers: boolean;
  theme: string;
  // Additional Monaco editor configurations
}

The component apply_editor_settings.ts (lines 20-27) consumes these settings to configure the Monaco editor instance used for command editing, applying font sizes, themes, and autocomplete behavior dynamically.

Workspace UI Components

Workspace creation and selection flow through the Dashboard pages in web/src/pages/Insight/Dashboard/. These React components:

  1. Issue HTTP POST requests to /layout when users create new workspaces
  2. Send layout metadata including type: "workspace", name, and description
  3. Handle workspace import/export through the same Layout API endpoints

When users click "Save Command" or "Load Command" in the DevTools interface, the front-end invokes the command API endpoints directly, persisting query text to the commands index and enabling cross-session reuse.

Summary

  • Workspaces are stored as Layout documents with Type = "workspace" in the layout index, managed by the Layout API in plugin/api/layout/.
  • Commands persist as CommonCommand documents in the dedicated commands index, handled by CommonCommand API handlers in plugin/api/index_management/.
  • Permission controls enforce access through PermissionCommandRead/Write and PermissionLayoutRead/Write constants.
  • Front-end integration occurs via React components in web/src/components/vendor/console/ and web/src/pages/Insight/Dashboard/, communicating with RESTful endpoints to provide seamless query management.

Frequently Asked Questions

What Elasticsearch indices store workspace and command data?

Workspaces reside in the layout index, registered in main.go at line 156. Commands reside in the commands index, registered at line 146 via orm.RegisterSchemaWithIndexName(elastic.CommonCommand{}, "commands").

How does the system prevent duplicate command titles?

The HandleAddCommonCommandAction handler in plugin/api/index_management/common_command.go (lines 40-81) validates the command title against existing documents before indexing. If a duplicate title exists within the user context, the API returns an error before the esClient.Index operation executes.

Which permissions control access to Developer Tools features?

The system defines four relevant permissions in core/security/enum/const.go: PermissionCommandRead and PermissionCommandWrite for query management, plus PermissionLayoutRead and PermissionLayoutWrite for workspace operations. These are enforced during route registration in plugin/api/init.go.

Where is the Monaco editor configuration applied?

The DevToolsSettings interface in web/src/components/vendor/console/services/settings.ts stores editor preferences. The apply_editor_settings.ts component (lines 20-27) applies these configurations to the Monaco editor instance, controlling font size, themes, and autocomplete behavior in the DevTools query interface.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →