npm package: @robinpath/sdk
Description: RobinPath SDK — embed RobinPath scripts in any JavaScript app
Author: Ryan Lee
Latest version: 0.1.1

# @robinpath/sdk

Embed [RobinPath](https://robinpath.com) scripts in any JavaScript or TypeScript application. Run scripts directly in-process — no CLI binary or HTTP server needed.

Works with React, Next.js, Vue, Angular, Express, Node.js, Bun, Deno, and any JS runtime.

## Install

```bash
npm install @robinpath/sdk
```

## Quick Start

```js
import { createRuntime } from '@robinpath/sdk';

const rp = createRuntime();
const result = await rp.run('log math.add 1 2');

console.log(result.ok);     // true
console.log(result.output);  // "3"
```

## API

### `createRuntime(options?)`

Creates a new RobinPath runtime instance.

```js
const rp = createRuntime({
  timeout: 5000,                    // Max execution time (ms)
  permissions: 'all',               // 'all' | 'none' | { fs, net, child, env, crypto }
  modules: ['math', 'string'],     // Whitelist allowed modules (undefined = all)
  customBuiltins: {                 // Add custom functions
    double: (args) => Number(args[0]) * 2,
  },
  customModules: [{                 // Add custom modules
    name: 'greet',
    functions: {
      hello: (args) => `Hello ${args[0]}!`,
    },
  }],
});
```

### `rp.run(script, context?)`

Execute a script and get the result.

```js
const result = await rp.run('log $name', { name: 'Robin' });

// result = {
//   ok: true,
//   output: 'Robin',
//   value: null,
//   logs: [...],
//   variables: { name: 'Robin' },
//   error: null,
//   stats: { duration_ms: 2, statements_executed: 1 }
// }
```

### `rp.stream(script, context?)`

Execute with real-time log streaming.

```js
const stream = rp.stream('log "a"\nlog "b"\nlog "c"');

stream.on('log', (log) => console.log('streamed:', log.message));
stream.on('done', (result) => console.log('done:', result.ok));

const result = await stream.result;
```

### `rp.setVariable(name, value)` / `rp.getVariable(name)`

Manage runtime state. Variables persist across `run()` calls.

```js
rp.setVariable('count', 0);
await rp.run('set $count = math.add $count 1');
console.log(rp.getVariable('count')); // 1
```

### `rp.registerBuiltin(name, handler)`

Add a custom function at runtime.

```js
rp.registerBuiltin('triple', (args) => Number(args[0]) * 3);
const r = await rp.run('set $r = triple 4\nlog $r');
// output: "12"
```

### `rp.registerModule(name, functions)`

Add a custom module at runtime.

```js
rp.registerModule('utils', {
  reverse: (args) => String(args[0]).split('').reverse().join(''),
});
const r = await rp.run('log utils.reverse "hello"');
// output: "olleh"
```

### `rp.parse(script)`

Parse a script and return the AST without executing.

```js
const ast = await rp.parse('set $x = 1');
// Returns array of AST nodes
```

### `rp.engine`

Access the underlying RobinPath engine for advanced use.

```js
const engine = rp.engine;
```

## Permissions

Control what scripts can access:

```js
// Allow everything (default)
createRuntime({ permissions: 'all' });

// Block everything
createRuntime({ permissions: 'none' });

// Granular control
createRuntime({
  permissions: {
    fs: false,      // Block file system (file, path, archive, excel, pdf)
    net: true,      // Allow network (http, net, dns, tls, fetch, email)
    child: false,   // Block child processes
    env: false,     // Block environment variables
    crypto: true,   // Allow crypto operations
  },
});
```

## Examples

### Multi-line script

```js
const rp = createRuntime();
const result = await rp.run(`
  set $a = 10
  set $b = 20
  set $sum = math.add $a $b
  log $sum
`);
console.log(result.output); // "30"
```

### Context variables

```js
const result = await rp.run('log $user.name', {
  user: { name: 'Robin', age: 25 },
});
console.log(result.output); // "Robin"
```

### Error handling

```js
const result = await rp.run('unknown_command');
if (!result.ok) {
  console.error(result.error.message);
}
```

### With timeout

```js
const rp = createRuntime({ timeout: 1000 });
const result = await rp.run('timer.sleep 5000');
// result.ok = false, result.error.message = "Execution timed out after 1000ms"
```

## TypeScript

Full type definitions included. Key types:

```ts
import type { RuntimeOptions, RunResult, RunStream, Permissions } from '@robinpath/sdk';
```

## License

MIT