@mastra/railway 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/README.md +135 -0
  3. package/package.json +68 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ # @mastra/railway
package/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # @mastra/railway
2
+
3
+ Railway cloud sandbox provider for [Mastra](https://mastra.ai) workspaces.
4
+
5
+ Implements the `WorkspaceSandbox` interface using [Railway Sandboxes](https://docs.railway.com/sandboxes) — ephemeral, isolated Linux VMs provisioned on demand through Railway's TypeScript SDK. Supports command execution with streaming output, command timeouts, configurable idle timeout, network isolation, and reattaching to an existing sandbox.
6
+
7
+ > Railway Sandboxes are available through Priority Boarding and the SDK may change in breaking ways between releases.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pnpm add @mastra/railway @mastra/core
13
+ ```
14
+
15
+ ## Configuration
16
+
17
+ The provider reads credentials from the environment by default:
18
+
19
+ | Option | Environment variable |
20
+ | --------------- | ------------------------ |
21
+ | `token` | `RAILWAY_API_TOKEN` |
22
+ | `environmentId` | `RAILWAY_ENVIRONMENT_ID` |
23
+
24
+ Pass them explicitly to override the environment values.
25
+
26
+ ## Usage
27
+
28
+ ### Basic
29
+
30
+ ```typescript
31
+ import { Workspace } from '@mastra/core/workspace';
32
+ import { RailwaySandbox } from '@mastra/railway';
33
+
34
+ const sandbox = new RailwaySandbox({
35
+ // token + environmentId read from RAILWAY_API_TOKEN / RAILWAY_ENVIRONMENT_ID
36
+ idleTimeoutMinutes: 30,
37
+ });
38
+
39
+ const workspace = new Workspace({ sandbox });
40
+ await workspace.init();
41
+
42
+ const result = await workspace.sandbox.executeCommand('echo', ['Hello!']);
43
+ console.log(result.stdout); // "Hello!"
44
+
45
+ await workspace.destroy();
46
+ ```
47
+
48
+ ### Private networking
49
+
50
+ Join the environment's private network to reach other services (for example
51
+ `postgres.railway.internal`):
52
+
53
+ ```typescript
54
+ const sandbox = new RailwaySandbox({
55
+ networkIsolation: 'PRIVATE',
56
+ env: { NODE_ENV: 'production' },
57
+ });
58
+ ```
59
+
60
+ ### Reattach to an existing sandbox
61
+
62
+ A Railway sandbox outlives the process that created it. Reconnect by its
63
+ Railway ID instead of provisioning a new one:
64
+
65
+ ```typescript
66
+ const sandbox = new RailwaySandbox({ sandboxId: 'existing-railway-sandbox-id' });
67
+ ```
68
+
69
+ ### Custom base image (templates)
70
+
71
+ Pre-install packages and run setup steps so every sandbox starts ready. Pass a
72
+ builder callback over the Railway template builder — it's built once on the
73
+ first `start()`:
74
+
75
+ ```typescript
76
+ const sandbox = new RailwaySandbox({
77
+ template: t => t.withPackages('git', 'curl').run('npm i -g pnpm').workdir('/app'),
78
+ });
79
+ ```
80
+
81
+ You can also pass a pre-built `SandboxTemplate` to reuse it across sandboxes
82
+ without rebuilding. Templates are ignored when `sandboxId` is set (reattach).
83
+
84
+ ### Fork a running sandbox
85
+
86
+ Clone a running sandbox's filesystem into a new, independent sandbox (a fresh
87
+ boot, not live processes). The returned `RailwaySandbox` is already started:
88
+
89
+ ```typescript
90
+ const child = await sandbox.fork({ idleTimeoutMinutes: 15 });
91
+ const result = await child.executeCommand('cat', ['/app/state.json']);
92
+ ```
93
+
94
+ ### Long-running processes
95
+
96
+ Use the process manager to spawn background commands and stream their output:
97
+
98
+ ```typescript
99
+ const handle = await sandbox.processes.spawn('npm run dev', {
100
+ onStdout: chunk => process.stdout.write(chunk),
101
+ });
102
+
103
+ // Later
104
+ await handle.kill();
105
+ ```
106
+
107
+ ## Options
108
+
109
+ | Option | Type | Description |
110
+ | -------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------ |
111
+ | `token` | `string` | Railway API token. Falls back to `RAILWAY_API_TOKEN`. |
112
+ | `environmentId` | `string` | Railway environment ID. Falls back to `RAILWAY_ENVIRONMENT_ID`. |
113
+ | `sandboxId` | `string` | Reattach to an existing Railway sandbox by ID instead of creating one. |
114
+ | `idleTimeoutMinutes` | `number` | Minutes a sandbox can sit idle before Railway destroys it. Range/default depend on the plan. |
115
+ | `networkIsolation` | `'ISOLATED' \| 'PRIVATE'` | Network mode. `ISOLATED` (default) is outbound-only; `PRIVATE` joins the private network. |
116
+ | `env` | `Record<string, string>` | Environment variables baked into the sandbox. |
117
+ | `template` | `SandboxTemplate \| (base) => SandboxTemplate` | Provision from a custom base image built with the Railway template builder. Ignored on reattach. |
118
+ | `timeout` | `number` | Default command timeout in milliseconds. Commands run until they exit when omitted. |
119
+ | `instructions` | `string \| (opts) => string` | Override the default agent instructions. |
120
+
121
+ ## Editor provider
122
+
123
+ Register the provider with `MastraEditor` to hydrate stored sandbox configs:
124
+
125
+ ```typescript
126
+ import { railwaySandboxProvider } from '@mastra/railway';
127
+
128
+ const editor = new MastraEditor({
129
+ sandboxes: { [railwaySandboxProvider.id]: railwaySandboxProvider },
130
+ });
131
+ ```
132
+
133
+ ## License
134
+
135
+ Apache-2.0
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@mastra/railway",
3
+ "version": "0.0.0",
4
+ "description": "Railway cloud sandbox provider for Mastra workspaces",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "scripts": {
22
+ "build": "tsup --silent --config tsup.config.ts",
23
+ "build:lib": "pnpm build",
24
+ "build:watch": "pnpm build --watch",
25
+ "test:unit": "vitest run --exclude '**/*.integration.test.ts'",
26
+ "test:watch": "vitest watch",
27
+ "test": "vitest run ./src/**/*.integration.test.ts",
28
+ "test:cloud": "pnpm test",
29
+ "lint": "eslint ."
30
+ },
31
+ "license": "Apache-2.0",
32
+ "dependencies": {
33
+ "railway": "^3.1.1"
34
+ },
35
+ "devDependencies": {
36
+ "@internal/lint": "workspace:*",
37
+ "@internal/types-builder": "workspace:*",
38
+ "@internal/workspace-test-utils": "workspace:*",
39
+ "@mastra/core": "workspace:*",
40
+ "@types/node": "22.19.15",
41
+ "@vitest/coverage-v8": "catalog:",
42
+ "@vitest/ui": "catalog:",
43
+ "dotenv": "^17.3.1",
44
+ "eslint": "^10.4.1",
45
+ "tsup": "^8.5.1",
46
+ "typescript": "catalog:",
47
+ "vitest": "catalog:"
48
+ },
49
+ "peerDependencies": {
50
+ "@mastra/core": ">=1.12.0-0 <2.0.0-0"
51
+ },
52
+ "files": [
53
+ "dist",
54
+ "CHANGELOG.md"
55
+ ],
56
+ "homepage": "https://mastra.ai",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/mastra-ai/mastra.git",
60
+ "directory": "workspaces/railway"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/mastra-ai/mastra/issues"
64
+ },
65
+ "engines": {
66
+ "node": ">=22.13.0"
67
+ }
68
+ }