Script
This document specifies the Script extension, a flexible data-layer solution that enables extensible functionality through multiple execution contexts. The Script extension provides a unified interface for custom logic execution within data processing workflows.
Supported script types include:
- LLM Tools: Callable tools for AI agents
- Table Actions: Custom actions triggered on table records
- Document Actions: Intelligent processing triggered on documents
- File Actions: One-click operations for background file processing
- User-Defined Functions (UDFs): Database functions callable in SQL queries
1. Introduction
Section titled “1. Introduction”The Script extension addresses the need for extensible data processing capabilities by providing a standardized framework for executing custom logic across multiple contexts. This specification defines the meta configuration structure and execution patterns for each supported script type.
2. Script Types and Specifications
Section titled “2. Script Types and Specifications”2.1 LLM Tool Scripts
Section titled “2.1 LLM Tool Scripts”2.1.1 Overview
Section titled “2.1.1 Overview”When the type property is set to "tool", scripts function as callable tools within Large Language Model (LLM) workflows, enabling AI agents to execute custom functions with structured input/output schemas.
2.1.2 Meta Configuration
Section titled “2.1.2 Meta Configuration”interface ToolMeta { type: "tool" funcName: string tool: { name: string description: string inputJSONSchema: JSONSchema outputJSONSchema: JSONSchema }}2.1.3 Implementation Example
Section titled “2.1.3 Implementation Example”export const meta = { type: "tool", funcName: "hello", tool: { name: "hello", description: "This is a hello world block", inputJSONSchema: { type: "object", properties: { name: { type: "string", }, }, }, outputJSONSchema: { type: "string", }, },}
export function hello({ name }: { name: string }) { return `Hello, ${name}!`}2.2 Table Action Scripts
Section titled “2.2 Table Action Scripts”2.2.1 Overview
Section titled “2.2.1 Overview”When the type property is set to "action", scripts serve as table-level operations that can be triggered on selected records. These actions extend the table interface with custom functionality accessible through context menus.
2.2.2 Meta Configuration
Section titled “2.2.2 Meta Configuration”interface ActionMeta { type: "tableAction" funcName: string tableAction: { name: string description: string }}2.2.3 Execution Context
Section titled “2.2.3 Execution Context”Table action functions receive two parameters:
input: The selected record data asRecord<string, any>ctx: Context object containingtableId,viewId, androwId
2.2.4 Implementation Example
Section titled “2.2.4 Implementation Example”export const meta = { type: "tableAction", funcName: "toggleChecked", tableAction: { name: "Toggle Checked Status", description: "Toggles the checked status of the selected record", },}
export async function toggleChecked( input: Record<string, any>, ctx: { tableId: string viewId: string rowId: string }) { const { tableId, viewId, rowId } = ctx await eidos.currentSpace.table(tableId).rows.update(rowId, { checked: !input.checked, }) return { success: true, }}2.3 Document Action Scripts
Section titled “2.3 Document Action Scripts”2.3.1 Overview
Section titled “2.3.1 Overview”When the type property is set to "docAction", scripts function as document-level operations that can be triggered on specific documents. These actions are accessible through the document actions menu, making your documents more intelligent and automated.
2.3.2 Meta Configuration
Section titled “2.3.2 Meta Configuration”interface DocActionMeta { type: "docAction" funcName: string docAction: { name: string description: string }}2.3.3 Execution Context
Section titled “2.3.3 Execution Context”Document action functions receive two parameters:
input: Input parameters asRecord<string, any>ctx: Context object containingdocId
2.3.4 Implementation Example
Section titled “2.3.4 Implementation Example”export const meta = { type: "docAction", funcName: "calculateCompletion", docAction: { name: "Calculate Completion", description: "Calculates the completion percentage of the document", },}
export async function calculateCompletion( input: Record<string, any>, ctx: { docId: string }) { const { docId } = ctx const doc = await eidos.currentSpace.doc.getMarkdown(docId)
// Extract completion ratio from markdown checkboxes const uncheckedCount = doc .split("\n") .filter((line) => line.startsWith("- [ ]")).length const checkedCount = doc .split("\n") .filter((line) => line.startsWith("- [x]")).length const totalCount = uncheckedCount + checkedCount const completion = totalCount > 0 ? (checkedCount / totalCount) * 100 : 0
await eidos.currentSpace.doc.setProperties(docId, { completion, })
return { completion, }}2.4 File Action Scripts
Section titled “2.4 File Action Scripts”2.4.1 Overview
Section titled “2.4.1 Overview”When the type property is set to "fileAction", scripts function as file-level actions that can be triggered on specific files. These actions are accessible through the file context menu, enabling background file processing without requiring a UI interface.
2.4.2 Meta Configuration
Section titled “2.4.2 Meta Configuration”interface FileActionMeta { type: "fileAction" funcName: string fileAction: { name: string description: string extensions: string[] // Supported file extensions, e.g., [".jpg", ".png"] icon?: string // Optional icon }}2.4.3 Execution Context
Section titled “2.4.3 Execution Context”File action functions receive two parameters:
filePath: File path string (same format as File Handler, supports~/and@/prefixes)ctx: Context object (currently empty, reserved for future extensions)
2.4.4 Implementation Example
Section titled “2.4.4 Implementation Example”export const meta = { type: "fileAction", funcName: "compressImage", fileAction: { name: "Compress Image", description: "Compress image to 50% of original size", extensions: [".jpg", ".jpeg", ".png"], icon: "🗜️" }}
export async function compressImage( filePath: string, ctx: Record<string, any>) { try { // Read original file const data = await eidos.currentSpace.fs.readFile(filePath)
// Compress image (using third-party library like browser-image-compression) const compressed = await compressImageData(data, { maxSizeMB: 1, maxWidthOrHeight: 1920 })
// Generate new file path const newPath = filePath.replace(/(\.\w+)$/, '_compressed$1') await eidos.currentSpace.fs.writeFile(newPath, compressed)
// Show success notification eidos.currentSpace.notify({ title: "Success", description: `Compressed and saved to ${newPath}` })
return { success: true, outputPath: newPath, originalSize: data.byteLength, compressedSize: compressed.byteLength } } catch (error) { eidos.currentSpace.notify({ title: "Error", description: `Compression failed: ${error.message}` }) return { success: false, error: error.message } }}2.4.5 User Experience Flow
Section titled “2.4.5 User Experience Flow”- User right-clicks a file in the file tree
- Sees “File Actions” submenu listing all
fileActionscripts supporting that extension - Clicks an action (e.g., “Compress Image”)
- Script executes in the background
- Notification displays upon completion
2.4.6 File Access API
Section titled “2.4.6 File Access API”Same as File Handler, use eidos.currentSpace.fs API to access files:
// Read text fileconst text = await eidos.currentSpace.fs.readFile(filePath, "utf8")
// Read binary fileconst data = await eidos.currentSpace.fs.readFile(filePath)
// Write fileawait eidos.currentSpace.fs.writeFile(filePath, content, "utf8")
// Get file infoconst stats = await eidos.currentSpace.fs.stat(filePath)For more file system API details, see Space API Reference - File System API.
2.5 User-Defined Function (UDF) Scripts
Section titled “2.5 User-Defined Function (UDF) Scripts”2.5.1 Overview
Section titled “2.5.1 Overview”When the type property is set to "udf", scripts create database functions that can be invoked within SQL queries, extending the database’s computational capabilities.
2.5.2 Meta Configuration
Section titled “2.5.2 Meta Configuration”interface UDFMeta { type: "udf" funcName: string udf: { name: string deterministic?: boolean }}2.5.3 UDF Types
Section titled “2.5.3 UDF Types”2.5.3.1 Scalar UDF
Section titled “2.5.3.1 Scalar UDF”Scalar UDFs operate on individual values and return a single result per invocation.
export const meta = { type: "udf", funcName: "add", udf: { // add is a reserved word in SQL, so we use a different name name: "myAdd", deterministic: true, },}
function add(a: number, b: number) { return a + b}3. Security Considerations
Section titled “3. Security Considerations”Script execution should be sandboxed appropriately to prevent unauthorized system access. Implementations must validate input parameters and enforce proper access controls based on the execution context.
4. Implementation Requirements
Section titled “4. Implementation Requirements”- All scripts MUST export a
metaobject conforming to the specified interface - Function names in the
meta.funcNameproperty MUST match the actual exported function - Input validation SHOULD be implemented for all script types
- Error handling MUST be consistent across all execution contexts
5. Future Extensions
Section titled “5. Future Extensions”This specification may be extended to support additional script types such as:
- Event handlers
- Data validators
- Custom field types
- Workflow triggers