moru-javascript

Moru JavaScript/TypeScript SDK

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "moru-javascript" with this command: npx skills add 1wos/sdkhackthon/1wos-sdkhackthon-moru-javascript

Moru JavaScript/TypeScript SDK

npm install @moru-ai/core

TypeScript types included.

Quick Start

import Sandbox from '@moru-ai/core'

const sbx = await Sandbox.create() try { await sbx.files.write("/app/script.py", "print('Hello from Moru!')") const result = await sbx.commands.run("python3 /app/script.py") console.log(result.stdout) } finally { await sbx.kill() }

Quick Reference

Task Code

Create sandbox await Sandbox.create() or await Sandbox.create("template")

Run command await sbx.commands.run("cmd")

Read file await sbx.files.read("/path")

Write file await sbx.files.write("/path", "content")

Background process await sbx.commands.run("cmd", { background: true })

Set timeout Sandbox.create({ timeoutMs: 600000 }) or sbx.setTimeout(600000)

Use volume Sandbox.create({ volumeId, volumeMountPath: "/workspace" })

Sandbox Lifecycle

Create

import Sandbox from '@moru-ai/core'

// Default template const sbx = await Sandbox.create()

// Specific template const sbx = await Sandbox.create("python")

// With options const sbx = await Sandbox.create("python", { timeoutMs: 600000, // milliseconds (default: 300000) metadata: { project: "myapp" }, envs: { API_KEY: "secret" }, volumeId: "vol_xxx", volumeMountPath: "/workspace", allowInternetAccess: true, })

Connect to Existing

const sbx = await Sandbox.connect("sbx_abc123") if (await sbx.isRunning()) { const result = await sbx.commands.run("echo still alive") }

Kill

await sbx.kill() // or await Sandbox.kill("sbx_abc123")

List All

for await (const info of Sandbox.list()) { console.log(${info.sandboxId}: ${info.state}) }

Running Commands

Basic

const result = await sbx.commands.run("echo hello") console.log(result.stdout) // "hello\n" console.log(result.stderr) // "" console.log(result.exitCode) // 0

With Options

const result = await sbx.commands.run("python3 script.py", { cwd: "/app", // Working directory user: "root", // Run as root envs: { DEBUG: "1" }, // Environment variables timeoutMs: 120000, // Command timeout (ms) onStdout: (data) => process.stdout.write(data), // Stream stdout onStderr: (data) => process.stderr.write(data), // Stream stderr })

Background Process

const handle = await sbx.commands.run("python3 server.py", { background: true })

// Get public URL const url = sbx.getHost(8080) console.log(Server at: ${url})

// Send input await handle.sendStdin("quit\n")

// Wait for completion const result = await handle.wait()

// Or kill it await handle.kill()

Process Management

// List running processes for (const proc of await sbx.commands.list()) { console.log(PID ${proc.pid}: ${proc.command}) }

// Kill by PID await sbx.commands.kill(1234)

Working with Files

Read/Write

// Write await sbx.files.write("/app/config.json", '{"key": "value"}')

// Read const content = await sbx.files.read("/app/config.json")

// Binary const bytes = await sbx.files.read("/app/image.png", { format: 'bytes' }) const blob = await sbx.files.read("/app/image.png", { format: 'blob' }) await sbx.files.write("/app/output.bin", binaryData)

// Stream large files const stream = await sbx.files.read("/app/large.bin", { format: 'stream' })

Multiple Files

await sbx.files.write([ { path: "/app/file1.txt", data: "content1" }, { path: "/app/file2.txt", data: "content2" }, ])

Directory Operations

// Check existence if (await sbx.files.exists("/app/config.json")) { const config = await sbx.files.read("/app/config.json") }

// List directory for (const entry of await sbx.files.list("/app")) { console.log(${entry.type}: ${entry.name} (${entry.size} bytes)) }

// Recursive list const entries = await sbx.files.list("/app", { depth: 5 })

// Get info const info = await sbx.files.getInfo("/app/file.txt") console.log(Size: ${info.size}, Modified: ${info.modifiedTime})

// Create directory await sbx.files.makeDir("/app/data")

// Delete await sbx.files.remove("/app/old_file.txt")

// Rename/Move await sbx.files.rename("/app/old.txt", "/app/new.txt")

Watch for Changes

const handle = await sbx.files.watchDir("/app", (event) => { console.log(${event.type}: ${event.name}) }) await handle.stop()

Volumes (Persistent Storage)

import Sandbox, { Volume } from '@moru-ai/core'

// Create volume (idempotent) const vol = await Volume.create({ name: "my-workspace" })

// Attach to sandbox const sbx = await Sandbox.create("base", { volumeId: vol.volumeId, volumeMountPath: "/workspace" // Must be /workspace, /data, /mnt, or /volumes })

// Data in /workspace persists after kill await sbx.commands.run("echo 'persistent' > /workspace/data.txt") await sbx.kill()

// Later - data still there const sbx2 = await Sandbox.create("base", { volumeId: vol.volumeId, volumeMountPath: "/workspace" }) const result = await sbx2.commands.run("cat /workspace/data.txt") console.log(result.stdout) // "persistent"

Volume Operations (No Sandbox Needed)

const vol = await Volume.get("my-workspace")

// List files for (const f of await vol.listFiles("/")) { console.log(${f.type}: ${f.name}) }

// Download/Upload const content = await vol.download("/data.txt") await vol.upload("/config.json", Buffer.from('{"key": "value"}'))

// Delete file await vol.delete("/old_file.txt")

// Delete volume (WARNING: permanent) await vol.delete()

Templates

import { Template, waitForPort } from '@moru-ai/core'

// Define template const template = Template() .fromPythonImage("3.11") .aptInstall(["curl", "git"]) .pipInstall(["flask", "pandas", "requests"]) .copy("./app", "/app") .setWorkdir("/app") .setEnvs({ FLASK_ENV: "production" }) .setStartCmd("python app.py", waitForPort(5000))

// Build const info = await Template.build(template, { alias: "my-flask-app" })

// Use const sbx = await Sandbox.create("my-flask-app")

From Dockerfile

const template = Template().fromDockerfile("./Dockerfile") await Template.build(template, { alias: "my-app" })

Build Options

await Template.build(template, { alias: "my-app", cpuCount: 4, memoryMB: 2048, onBuildLogs: (entry) => console.log(entry.message), })

// Background build const info = await Template.buildInBackground(template, { alias: "my-app" }) const status = await Template.getBuildStatus(info) // building, success, failed

Error Handling

import Sandbox, { SandboxError, // Base TimeoutError, // Operation timed out NotFoundError, // Resource not found AuthenticationError, // Invalid API key NotEnoughSpaceError, // Disk full CommandExitError, // Non-zero exit (has exitCode, stdout, stderr) } from '@moru-ai/core'

try { const sbx = await Sandbox.create() try { const result = await sbx.commands.run("python3 script.py", { timeoutMs: 30000 }) } finally { await sbx.kill() } } catch (error) { if (error instanceof TimeoutError) { console.log("Command timed out") } else if (error instanceof CommandExitError) { console.log(Failed with exit code ${error.exitCode}: ${error.stderr}) } else if (error instanceof AuthenticationError) { console.log("Invalid API key - check MORU_API_KEY") } }

TypeScript Types

import type { SandboxOpts, SandboxInfo, CommandResult, CommandStartOpts, EntryInfo, VolumeInfo, } from '@moru-ai/core'

Common Pitfalls

Always cleanup sandboxes

// ❌ WRONG const sbx = await Sandbox.create() await sbx.commands.run("echo hello") // Forgot to kill - sandbox keeps running!

// ✅ CORRECT const sbx = await Sandbox.create() try { await sbx.commands.run("echo hello") } finally { await sbx.kill() }

Don't assume packages exist

// ❌ WRONG await sbx.commands.run("python3 -c 'import pandas'") // ImportError!

// ✅ CORRECT await sbx.commands.run("pip install pandas", { timeoutMs: 120000 }) await sbx.commands.run("python3 -c 'import pandas'")

Write to volume path for persistence

// ❌ WRONG - lost on kill await sbx.files.write("/home/user/data.txt", "important")

// ✅ CORRECT - persisted await sbx.files.write("/workspace/data.txt", "important")

Handle command failures

const result = await sbx.commands.run("python3 script.py") if (result.exitCode !== 0) { console.log(Error: ${result.stderr}) }

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

moru-python

No summary provided by upstream source.

Repository SourceNeeds Review
General

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

moru

No summary provided by upstream source.

Repository SourceNeeds Review