Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Spacedrive Official Extensions

This directory contains the extension SDK and official extensions for Spacedrive.

Structure

extensions/ ├── spacedrive-sdk/ # Core SDK library ├── spacedrive-sdk-macros/ # Proc macros for beautiful API ├── test-extension/ # Example extension with beautiful API └── finance/ # (Future) First revenue-generating extension 

Quick Start

1. Install WASM Target

rustup target add wasm32-unknown-unknown

2. Create Extension

cargo new --lib my-extension cd my-extension

Cargo.toml:

[lib] crate-type = ["cdylib"] [dependencies] spacedrive-sdk = { path = "../spacedrive-sdk" } serde = { version = "1.0", features = ["derive"] }

src/lib.rs:

use spacedrive_sdk::prelude::*; use spacedrive_sdk::{extension, job}; #[extension(  id = "my-extension",  name = "My Extension",  version = "0.1.0" )] struct MyExtension; #[derive(Serialize, Deserialize, Default)] pub struct MyJobState { pub counter: u32, } #[job] fn my_job(ctx: &JobContext, state: &mut MyJobState) -> Result<()> { ctx.log("Job starting!"); state.counter += 1; ctx.report_progress(1.0, "Done!"); Ok(()) }

3. Build

cargo build --target wasm32-unknown-unknown --release cp target/wasm32-unknown-unknown/release/my_extension.wasm .

4. Create manifest.json

{ "id": "my-extension", "name": "My Extension", "version": "0.1.0", "wasm_file": "my_extension.wasm", "permissions": { "methods": ["vdfs.*", "ai.*"], "libraries": ["*"] } }

The Beautiful API

Before Macros (Manual FFI):

#[no_mangle] pub extern "C" fn execute_my_job( ctx_ptr: u32, ctx_len: u32, state_ptr: u32, state_len: u32 ) -> i32 { let ctx_json = unsafe { /* 30 lines of pointer manipulation */ }; let mut state = /* 40 lines of deserialization */; // ... business logic buried in boilerplate ... }

180+ lines, lots of unsafe

After Macros (Beautiful):

#[job] fn my_job(ctx: &JobContext, state: &mut MyJobState) -> Result<()> { // Just write business logic! ctx.log("Working..."); state.counter += 1; Ok(()) }

60-80 lines, zero unsafe, pure logic

API Reference

Extension Container

#[extension(  id = "finance",  name = "Spacedrive Finance",  version = "0.1.0" )] struct Finance;

Generates:

  • plugin_init() export
  • plugin_cleanup() export
  • Metadata for manifest generation

Job Definition

#[job] fn email_scan(ctx: &JobContext, state: &mut EmailScanState) -> Result<()> { // Progress reporting ctx.report_progress(0.5, "Half done"); // Checkpointing ctx.checkpoint(state)?; // Interruption handling if ctx.check_interrupt() { return Err(Error::OperationFailed("Interrupted".into())); } // Metrics ctx.increment_items(1); ctx.increment_bytes(1000); // Warnings ctx.add_warning("Non-fatal issue"); // Full SDK access let entry = ctx.vdfs().create_entry(...)?; let ocr = ctx.ai().ocr(&pdf, ...)?; Ok(()) }

VDFS Operations

// Create entries let entry = ctx.vdfs().create_entry(CreateEntry { name: "My File".into(), path: "path/to/file".into(), entry_type: "Document".into(), metadata: None, })?; // Write sidecars ctx.vdfs().write_sidecar(entry.id, "metadata.json", data)?; // Read sidecars let data = ctx.vdfs().read_sidecar(entry.id, "metadata.json")?;

AI Operations

// OCR let ocr = ctx.ai().ocr(&pdf_bytes, OcrOptions::default())?; // Classification let result = ctx.ai().classify_text(&text, "Extract data")?; // Embeddings let embedding = ctx.ai().embed("query text")?;

Credentials

// Store OAuth ctx.credentials().store("gmail", Credential::oauth2( access_token, Some(refresh_token), 3600, vec!["https://www.googleapis.com/auth/gmail.readonly".into()] ))?; // Get (auto-refreshes) let cred = ctx.credentials().get("gmail")?;

Examples

See extensions/test-extension/ for a complete working example.

Building

All extensions:

cd extensions/test-extension cargo build --target wasm32-unknown-unknown --release

Documentation


Extension development is now beautiful, safe, and productive. Start building!