@assemblyline-agents/railway 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenEve contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ # @assemblyline-agents/railway
2
+
3
+ Official Assembly Line Railway deployment plugin.
4
+
5
+ It implements Assembly Line's deploy provider contract for Railway, including helper support for provisioning a Railway Postgres database to back the agent's durable state. The Assembly Line CLI uses this provider when a project targets Railway; a bundled skill under `skills/` covers Railway-specific workflows.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install @assemblyline-agents/railway
11
+ ```
12
+
13
+ ## Part of Assembly Line
14
+
15
+ This package is part of [Assembly Line](https://github.com/jasonbadeaux/openeve), a vendor-neutral, filesystem-first framework for durable AI agents. See the developer documentation in [docs/developers/](https://github.com/jasonbadeaux/openeve/tree/main/docs/developers) for setup, agent authoring, and deployment guides.
16
+
17
+ ## License
18
+
19
+ MIT
@@ -0,0 +1,63 @@
1
+ import { type AdapterDefinition, type AdapterProviderMetadata, type DeployArtifact, type DeployPlan, type DeployPublisher, type JsonObject, type McpPluginConnectionOptions, type ProviderModule, type RunDeployCommand } from "@assemblyline-agents/core";
2
+ export { ensureRailwayPostgres, parseRailwayEnvironmentServices, railwayPostgresReferenceArgs, railwayPostgresStatusArgs, type RailwayPostgresResult } from "./postgres.js";
3
+ export type RailwayConnectionOptions = McpPluginConnectionOptions;
4
+ export declare function defineRailwayConnection(options: RailwayConnectionOptions): import("@assemblyline-agents/core").McpHttpClientConnectionDefinition;
5
+ export declare const openevePlugin: import("@assemblyline-agents/core").PluginModule;
6
+ /** Metadata owned by this package; the core registry mirrors it as an offline default. */
7
+ export declare const RAILWAY_DEPLOY_PROVIDER_METADATA: AdapterProviderMetadata;
8
+ export declare const openeveProvider: ProviderModule;
9
+ export type { DeployArtifact as DeployArtifactLike, DeployCommandOptions, DeployCommandResult, DeployPlan as DeployPlanLike } from "@assemblyline-agents/core";
10
+ export interface RailwayDeployAdapter extends AdapterDefinition {
11
+ kind: "railway";
12
+ }
13
+ export interface RailwayDeployOptions extends JsonObject {
14
+ project?: string;
15
+ service?: string;
16
+ environment?: string;
17
+ }
18
+ export interface RailwayDeployPublisherOptions {
19
+ railwayBin?: string;
20
+ project?: string;
21
+ service?: string;
22
+ json?: boolean;
23
+ detach?: boolean;
24
+ cwd?: string;
25
+ state?: AdapterDefinition;
26
+ env?: Record<string, string | undefined>;
27
+ runCommand: RunDeployCommand;
28
+ runInteractiveCommand?: RunDeployCommand;
29
+ now?: () => Date;
30
+ }
31
+ export declare const RAILWAY_CODEX_VOLUME_MOUNT_PATH = "/data";
32
+ export declare const RAILWAY_CODEX_HOME = "/data/codex";
33
+ export interface RailwayVolumeSummary {
34
+ id: string;
35
+ mountPath: string;
36
+ name?: string;
37
+ serviceName?: string;
38
+ status?: string;
39
+ }
40
+ export interface RailwayCodexVolumeResult {
41
+ status: "created" | "reused";
42
+ mountPath: typeof RAILWAY_CODEX_VOLUME_MOUNT_PATH;
43
+ volume?: RailwayVolumeSummary;
44
+ }
45
+ export declare function railwayDeploy(options?: RailwayDeployOptions): RailwayDeployAdapter;
46
+ export declare function railwayDeployArgs(artifact: DeployArtifact, plan: DeployPlan, options: RailwayDeployPublisherOptions): string[];
47
+ export declare function railwayVolumeListArgs(plan: DeployPlan, options: RailwayDeployPublisherOptions): string[];
48
+ export declare function railwayVolumeAddArgs(plan: DeployPlan, options: RailwayDeployPublisherOptions): string[];
49
+ export declare function railwayCodexSshArgs(plan: DeployPlan, options: Pick<RailwayDeployPublisherOptions, "project" | "service">, command: string[]): string[];
50
+ export declare function parseRailwayVolumes(text: string): RailwayVolumeSummary[];
51
+ export declare function artifactUsesCodexOAuth(artifact: DeployArtifact): boolean;
52
+ export declare function ensureRailwayCodexVolume(artifact: DeployArtifact, plan: DeployPlan, options: RailwayDeployPublisherOptions): Promise<RailwayCodexVolumeResult | undefined>;
53
+ export declare function inspectRailwayCodexVolume(plan: DeployPlan, options: RailwayDeployPublisherOptions): Promise<RailwayVolumeSummary | undefined>;
54
+ /**
55
+ * `railway variables --set "K=V"` args for one secret sync. One `--set` per
56
+ * key, scoped to the service/environment. Exported for unit coverage — live
57
+ * behavior is gated on the credential smoke suite.
58
+ */
59
+ export declare function railwaySecretsArgs(keys: string[], secrets: Record<string, string>, plan: DeployPlan, options: RailwayDeployPublisherOptions): string[];
60
+ /** `railway environment delete` operates on the cwd-linked project; exported for unit coverage. */
61
+ export declare function railwayEnvironmentDeleteArgs(plan: DeployPlan): string[];
62
+ export declare function createRailwayDeployPublisher(options: RailwayDeployPublisherOptions): DeployPublisher;
63
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EAGnB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACtB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,qBAAqB,EACrB,+BAA+B,EAC/B,4BAA4B,EAC5B,yBAAyB,EACzB,KAAK,qBAAqB,EAC3B,MAAM,eAAe,CAAC;AAGvB,MAAM,MAAM,wBAAwB,GAAG,0BAA0B,CAAC;AAClE,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,yEAExE;AACD,eAAO,MAAM,aAAa,kDAA6D,CAAC;AAExF,0FAA0F;AAC1F,eAAO,MAAM,gCAAgC,EAAE,uBAc9C,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,cA0B7B,CAAC;AAoCF,YAAY,EACV,cAAc,IAAI,kBAAkB,EACpC,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,IAAI,cAAc,EAC7B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,qBAAqB,CAAC,EAAE,gBAAgB,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,eAAO,MAAM,+BAA+B,UAAU,CAAC;AACvD,eAAO,MAAM,kBAAkB,gBAA6C,CAAC;AAE7E,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,SAAS,EAAE,OAAO,+BAA+B,CAAC;IAClD,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,oBAAoB,CAMtF;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,6BAA6B,GAAG,MAAM,EAAE,CAM9H;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,6BAA6B,GAAG,MAAM,EAAE,CAExG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,6BAA6B,GAAG,MAAM,EAAE,CAEvG;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,IAAI,CAAC,6BAA6B,EAAE,SAAS,GAAG,SAAS,CAAC,EACnE,OAAO,EAAE,MAAM,EAAE,GAChB,MAAM,EAAE,CAMV;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAkBxE;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAExE;AAOD,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAW/C;AAED,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,CAW3C;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,6BAA6B,GACrC,MAAM,EAAE,CAOV;AAED,mGAAmG;AACnG,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,CAEvE;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,6BAA6B,GAAG,eAAe,CAuGpG"}
package/dist/index.js ADDED
@@ -0,0 +1,349 @@
1
+ import { spawn } from "node:child_process";
2
+ import { adapter, connectionPluginMetadata, defineMcpPluginConnection, definePlugin } from "@assemblyline-agents/core";
3
+ import { ensureRailwayPostgres } from "./postgres.js";
4
+ export { ensureRailwayPostgres, parseRailwayEnvironmentServices, railwayPostgresReferenceArgs, railwayPostgresStatusArgs } from "./postgres.js";
5
+ const RAILWAY_CONNECTION_PLUGIN = connectionPluginMetadata("railway");
6
+ export function defineRailwayConnection(options) {
7
+ return defineMcpPluginConnection(RAILWAY_CONNECTION_PLUGIN, options);
8
+ }
9
+ export const openevePlugin = definePlugin({ connections: [RAILWAY_CONNECTION_PLUGIN] });
10
+ /** Metadata owned by this package; the core registry mirrors it as an offline default. */
11
+ export const RAILWAY_DEPLOY_PROVIDER_METADATA = {
12
+ kind: "railway",
13
+ role: "deploy",
14
+ packageName: "@assemblyline-agents/railway",
15
+ requiredEnv: ["RAILWAY_TOKEN"],
16
+ capabilities: ["hosted-node-runtime", "persistent-storage", "remote-exec"],
17
+ setup: [
18
+ {
19
+ kind: "deploy",
20
+ name: "railway-project",
21
+ required: true,
22
+ message: "Configure a Railway project/service before publishing."
23
+ }
24
+ ]
25
+ };
26
+ export const openeveProvider = {
27
+ providers: [
28
+ {
29
+ metadata: RAILWAY_DEPLOY_PROVIDER_METADATA,
30
+ create(ctx) {
31
+ const project = stringOption(ctx.options, "project") ?? ctx.env.RAILWAY_PROJECT_ID;
32
+ const service = stringOption(ctx.options, "service") ?? ctx.env.RAILWAY_SERVICE_ID;
33
+ const railwayBin = stringOption(ctx.options, "railwayBin");
34
+ const json = booleanOption(ctx.options, "json");
35
+ const detach = booleanOption(ctx.options, "detach");
36
+ const cwd = stringOption(ctx.options, "cwd");
37
+ return createRailwayDeployPublisher({
38
+ ...(railwayBin ? { railwayBin } : {}),
39
+ ...(project ? { project } : {}),
40
+ ...(service ? { service } : {}),
41
+ ...(json !== undefined ? { json } : {}),
42
+ ...(detach !== undefined ? { detach } : {}),
43
+ ...(cwd ? { cwd } : {}),
44
+ ...(ctx.manifest?.gateway.state ? { state: ctx.manifest.gateway.state } : {}),
45
+ env: ctx.env,
46
+ runCommand: spawnDeployCommand,
47
+ runInteractiveCommand: spawnInteractiveDeployCommand
48
+ });
49
+ }
50
+ }
51
+ ]
52
+ };
53
+ const spawnDeployCommand = (executable, args, options = {}) => {
54
+ return new Promise((resolvePromise, reject) => {
55
+ const child = spawn(executable, args, {
56
+ cwd: options.cwd ?? process.cwd(),
57
+ env: (options.env ?? process.env),
58
+ stdio: ["ignore", "pipe", "pipe"]
59
+ });
60
+ let stdout = "";
61
+ let stderr = "";
62
+ child.stdout.on("data", (chunk) => {
63
+ stdout += chunk.toString("utf8");
64
+ });
65
+ child.stderr.on("data", (chunk) => {
66
+ stderr += chunk.toString("utf8");
67
+ });
68
+ child.on("error", reject);
69
+ child.on("close", (code) => {
70
+ resolvePromise({ exitCode: code ?? 1, stdout, stderr });
71
+ });
72
+ });
73
+ };
74
+ const spawnInteractiveDeployCommand = (executable, args, options = {}) => {
75
+ return new Promise((resolvePromise, reject) => {
76
+ const child = spawn(executable, args, {
77
+ cwd: options.cwd ?? process.cwd(),
78
+ env: (options.env ?? process.env),
79
+ stdio: "inherit"
80
+ });
81
+ child.on("error", reject);
82
+ child.on("close", (code) => resolvePromise({ exitCode: code ?? 1, stdout: "", stderr: "" }));
83
+ });
84
+ };
85
+ export const RAILWAY_CODEX_VOLUME_MOUNT_PATH = "/data";
86
+ export const RAILWAY_CODEX_HOME = `${RAILWAY_CODEX_VOLUME_MOUNT_PATH}/codex`;
87
+ export function railwayDeploy(options = {}) {
88
+ const metadata = RAILWAY_DEPLOY_PROVIDER_METADATA;
89
+ const definition = { ...adapter("railway", options), kind: "railway" };
90
+ if (metadata.requiredEnv)
91
+ definition.requiredEnv = metadata.requiredEnv;
92
+ if (metadata.capabilities)
93
+ definition.capabilities = metadata.capabilities;
94
+ return definition;
95
+ }
96
+ export function railwayDeployArgs(artifact, plan, options) {
97
+ const args = ["up", artifact.root, "--path-as-root", options.detach ? "--detach" : "--ci", "--environment", plan.environment];
98
+ if (options.project)
99
+ args.push("--project", options.project);
100
+ if (options.service)
101
+ args.push("--service", options.service);
102
+ if (options.json)
103
+ args.push("--json");
104
+ return args;
105
+ }
106
+ export function railwayVolumeListArgs(plan, options) {
107
+ return [...railwayVolumeScopeArgs(plan, options), "list", "--json"];
108
+ }
109
+ export function railwayVolumeAddArgs(plan, options) {
110
+ return [...railwayVolumeScopeArgs(plan, options), "add", "--mount-path", RAILWAY_CODEX_VOLUME_MOUNT_PATH, "--json"];
111
+ }
112
+ export function railwayCodexSshArgs(plan, options, command) {
113
+ const args = ["ssh"];
114
+ if (options.project)
115
+ args.push("--project", options.project);
116
+ if (options.service)
117
+ args.push("--service", options.service);
118
+ args.push("--environment", plan.environment, ...command);
119
+ return args;
120
+ }
121
+ export function parseRailwayVolumes(text) {
122
+ let parsed;
123
+ try {
124
+ parsed = JSON.parse(text);
125
+ }
126
+ catch {
127
+ throw new Error("Railway volume list did not return valid JSON. Update the Railway CLI and retry.");
128
+ }
129
+ if (!isRecord(parsed) || !Array.isArray(parsed.volumes)) {
130
+ throw new Error("Railway volume list returned an unsupported response shape. Update the Railway CLI and retry.");
131
+ }
132
+ return parsed.volumes.flatMap((value) => {
133
+ if (!isRecord(value) || typeof value.id !== "string" || typeof value.mountPath !== "string")
134
+ return [];
135
+ const volume = { id: value.id, mountPath: value.mountPath };
136
+ if (typeof value.name === "string")
137
+ volume.name = value.name;
138
+ if (typeof value.serviceName === "string")
139
+ volume.serviceName = value.serviceName;
140
+ if (typeof value.status === "string")
141
+ volume.status = value.status;
142
+ return [volume];
143
+ });
144
+ }
145
+ export function artifactUsesCodexOAuth(artifact) {
146
+ return artifact.manifest?.agent?.model.startsWith("openai-codex/") ?? false;
147
+ }
148
+ function artifactRequiresPersistentPath(artifact, path) {
149
+ return artifact.manifest?.deploymentRequirements?.persistentDirectories.some((entry) => entry.path === path)
150
+ ?? (path === RAILWAY_CODEX_VOLUME_MOUNT_PATH && artifactUsesCodexOAuth(artifact));
151
+ }
152
+ export async function ensureRailwayCodexVolume(artifact, plan, options) {
153
+ if (!artifactRequiresPersistentPath(artifact, RAILWAY_CODEX_VOLUME_MOUNT_PATH))
154
+ return undefined;
155
+ const existing = await inspectRailwayCodexVolume(plan, options);
156
+ if (existing)
157
+ return { status: "reused", mountPath: RAILWAY_CODEX_VOLUME_MOUNT_PATH, volume: existing };
158
+ const railwayBin = options.railwayBin ?? "railway";
159
+ const commandOptions = deployCommandOptions(options);
160
+ const addResult = await options.runCommand(railwayBin, railwayVolumeAddArgs(plan, options), commandOptions);
161
+ if (addResult.exitCode !== 0) {
162
+ throw new Error(`Railway Codex OAuth volume provisioning failed with exit code ${addResult.exitCode}.`);
163
+ }
164
+ return { status: "created", mountPath: RAILWAY_CODEX_VOLUME_MOUNT_PATH };
165
+ }
166
+ export async function inspectRailwayCodexVolume(plan, options) {
167
+ const railwayBin = options.railwayBin ?? "railway";
168
+ const listResult = await options.runCommand(railwayBin, railwayVolumeListArgs(plan, options), deployCommandOptions(options));
169
+ if (listResult.exitCode !== 0) {
170
+ throw new Error(`Railway Codex OAuth volume preflight failed with exit code ${listResult.exitCode}.`);
171
+ }
172
+ return parseRailwayVolumes(listResult.stdout).find((volume) => volume.mountPath === RAILWAY_CODEX_VOLUME_MOUNT_PATH);
173
+ }
174
+ /**
175
+ * `railway variables --set "K=V"` args for one secret sync. One `--set` per
176
+ * key, scoped to the service/environment. Exported for unit coverage — live
177
+ * behavior is gated on the credential smoke suite.
178
+ */
179
+ export function railwaySecretsArgs(keys, secrets, plan, options) {
180
+ const args = ["variables"];
181
+ for (const key of keys)
182
+ args.push("--set", `${key}=${secrets[key]}`);
183
+ if (options.service)
184
+ args.push("--service", options.service);
185
+ args.push("--environment", plan.environment);
186
+ if (options.project)
187
+ args.push("--project", options.project);
188
+ return args;
189
+ }
190
+ /** `railway environment delete` operates on the cwd-linked project; exported for unit coverage. */
191
+ export function railwayEnvironmentDeleteArgs(plan) {
192
+ return ["environment", "delete", plan.environment, "--yes"];
193
+ }
194
+ export function createRailwayDeployPublisher(options) {
195
+ return {
196
+ target: "railway",
197
+ async destroy(_artifact, plan, destroyOptions = {}) {
198
+ // Deleting a Railway environment removes every service instance,
199
+ // variable, volume, and database inside it — there is no keep-data
200
+ // teardown. Require the explicit data confirmation.
201
+ if (!destroyOptions.purgeData) {
202
+ throw new Error(`Railway destroy deletes the "${plan.environment}" environment including its databases and volumes. Pass --purge-data to confirm.`);
203
+ }
204
+ const railwayBin = options.railwayBin ?? "railway";
205
+ const result = await options.runCommand(railwayBin, railwayEnvironmentDeleteArgs(plan), deployCommandOptions(options));
206
+ if (result.exitCode !== 0) {
207
+ throw new Error(`Railway environment delete failed with exit code ${result.exitCode}. The CLI acts on the cwd-linked project; run \`railway link\` first if this project is not linked.`);
208
+ }
209
+ return {
210
+ target: "railway",
211
+ status: "destroyed",
212
+ environment: plan.environment,
213
+ ...(options.project ? { project: options.project } : {}),
214
+ completedAt: new Date().toISOString()
215
+ };
216
+ },
217
+ async syncSecrets(secrets, plan) {
218
+ const railwayBin = options.railwayBin ?? "railway";
219
+ const syncedKeys = [];
220
+ const skippedKeys = [];
221
+ for (const [key, value] of Object.entries(secrets)) {
222
+ (value ? syncedKeys : skippedKeys).push(key);
223
+ }
224
+ if (syncedKeys.length > 0) {
225
+ const commandOptions = {};
226
+ if (options.cwd)
227
+ commandOptions.cwd = options.cwd;
228
+ if (options.env)
229
+ commandOptions.env = options.env;
230
+ const args = railwaySecretsArgs(syncedKeys, secrets, plan, options);
231
+ const result = await options.runCommand(railwayBin, args, commandOptions);
232
+ if (result.exitCode !== 0) {
233
+ throw new Error(`Railway variable sync failed with exit code ${result.exitCode}.`);
234
+ }
235
+ }
236
+ return { target: "railway", syncedKeys, skippedKeys };
237
+ },
238
+ async runRemoteCommand(artifact, plan, command, commandOptions = {}) {
239
+ if (artifactRequiresPersistentPath(artifact, RAILWAY_CODEX_VOLUME_MOUNT_PATH)) {
240
+ if (command.join(" ") === "codex login status") {
241
+ const volume = await inspectRailwayCodexVolume(plan, options);
242
+ if (!volume)
243
+ return { exitCode: 1, stdout: "", stderr: "Codex OAuth volume is not provisioned." };
244
+ }
245
+ else {
246
+ await ensureRailwayCodexVolume(artifact, plan, options);
247
+ }
248
+ }
249
+ const railwayBin = options.railwayBin ?? "railway";
250
+ const runner = commandOptions.interactive && options.runInteractiveCommand
251
+ ? options.runInteractiveCommand
252
+ : options.runCommand;
253
+ return runner(railwayBin, railwayCodexSshArgs(plan, options, command), {
254
+ ...deployCommandOptions(options),
255
+ ...(commandOptions.silent !== undefined ? { silent: commandOptions.silent } : {})
256
+ });
257
+ },
258
+ async publish(artifact, plan) {
259
+ const railwayBin = options.railwayBin ?? "railway";
260
+ const args = railwayDeployArgs(artifact, plan, options);
261
+ const postgres = await ensureRailwayPostgres(options.state, plan, options);
262
+ const codexOAuthVolume = await ensureRailwayCodexVolume(artifact, plan, options);
263
+ const commandOptions = deployCommandOptions(options);
264
+ const result = await options.runCommand(railwayBin, args, commandOptions);
265
+ if (result.exitCode !== 0) {
266
+ throw new Error(`Railway deploy failed with exit code ${result.exitCode}.`);
267
+ }
268
+ // `deploymentUrl` is the reachable service URL when the CLI prints one.
269
+ // Reliably resolving it from the Railway API (the domain endpoint) is the
270
+ // remaining smoke-gated step; until then callers get the CLI-scraped URL
271
+ // or null, and the dashboard link separately so the two never conflate.
272
+ const receipt = {
273
+ target: "railway",
274
+ status: "published",
275
+ environment: plan.environment,
276
+ agentRevision: plan.agentRevision,
277
+ artifactRoot: artifact.root,
278
+ ...(options.project ? { project: options.project } : {}),
279
+ ...(options.service ? { service: options.service } : {}),
280
+ deploymentUrl: firstRuntimeUrl(result.stdout) ?? null,
281
+ dashboardUrl: options.project
282
+ ? `https://railway.app/project/${options.project}`
283
+ : "https://railway.app/dashboard",
284
+ ...(postgres ? { postgres } : {}),
285
+ ...(codexOAuthVolume ? {
286
+ codexOAuth: {
287
+ mode: "device-auth",
288
+ home: RAILWAY_CODEX_HOME,
289
+ volume: codexOAuthVolume
290
+ }
291
+ } : {}),
292
+ command: {
293
+ executable: railwayBin,
294
+ args
295
+ },
296
+ completedAt: (options.now?.() ?? new Date()).toISOString()
297
+ };
298
+ return receipt;
299
+ }
300
+ };
301
+ }
302
+ function firstRuntimeUrl(text) {
303
+ for (const match of text.matchAll(/https?:\/\/\S+/gu)) {
304
+ const url = match[0]?.replace(/[),.]+$/u, "");
305
+ if (url && !isRailwayDashboardUrl(url))
306
+ return url;
307
+ }
308
+ return undefined;
309
+ }
310
+ function isRailwayDashboardUrl(url) {
311
+ try {
312
+ const parsed = new URL(url);
313
+ const host = parsed.hostname.toLowerCase();
314
+ const path = parsed.pathname.toLowerCase();
315
+ return (host === "railway.app" || host === "railway.com") && (path.startsWith("/project") || path.startsWith("/dashboard"));
316
+ }
317
+ catch {
318
+ return false;
319
+ }
320
+ }
321
+ function railwayVolumeScopeArgs(plan, options) {
322
+ const args = ["volume"];
323
+ if (options.project)
324
+ args.push("--project", options.project);
325
+ if (options.service)
326
+ args.push("--service", options.service);
327
+ args.push("--environment", plan.environment);
328
+ return args;
329
+ }
330
+ function deployCommandOptions(options) {
331
+ const commandOptions = {};
332
+ if (options.cwd)
333
+ commandOptions.cwd = options.cwd;
334
+ if (options.env)
335
+ commandOptions.env = options.env;
336
+ return commandOptions;
337
+ }
338
+ function isRecord(value) {
339
+ return typeof value === "object" && value !== null && !Array.isArray(value);
340
+ }
341
+ function stringOption(options, name) {
342
+ const value = options[name];
343
+ return typeof value === "string" ? value : undefined;
344
+ }
345
+ function booleanOption(options, name) {
346
+ const value = options[name];
347
+ return typeof value === "boolean" ? value : undefined;
348
+ }
349
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { AdapterDefinition, DeployPlan, RunDeployCommand } from "@assemblyline-agents/core";
2
+ interface RailwayPostgresCommandOptions {
3
+ railwayBin?: string;
4
+ project?: string;
5
+ service?: string;
6
+ cwd?: string;
7
+ env?: Record<string, string | undefined>;
8
+ runCommand: RunDeployCommand;
9
+ }
10
+ interface RailwayServiceSummary {
11
+ id?: string;
12
+ name: string;
13
+ }
14
+ export interface RailwayPostgresResult {
15
+ status: "created" | "reused";
16
+ service: RailwayServiceSummary;
17
+ appService: string;
18
+ connectionEnv: "DATABASE_URL";
19
+ reference: string;
20
+ }
21
+ export declare function railwayPostgresStatusArgs(plan: DeployPlan, options: RailwayPostgresCommandOptions): string[];
22
+ export declare function railwayPostgresReferenceArgs(plan: DeployPlan, options: RailwayPostgresCommandOptions, appService: string, databaseService: string): string[];
23
+ export declare function parseRailwayEnvironmentServices(text: string, environment: string): {
24
+ projectId?: string;
25
+ services: RailwayServiceSummary[];
26
+ };
27
+ export declare function ensureRailwayPostgres(state: AdapterDefinition | undefined, plan: DeployPlan, options: RailwayPostgresCommandOptions): Promise<RailwayPostgresResult | undefined>;
28
+ export {};
29
+ //# sourceMappingURL=postgres.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAEjB,UAAU,EACV,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,6BAA6B;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,UAAU,qBAAqB;IAC7B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,OAAO,EAAE,qBAAqB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,cAAc,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,6BAA6B,GAAG,MAAM,EAAE,CAK5G;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,6BAA6B,EACtC,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB,MAAM,EAAE,CAMV;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC,CAaA;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,iBAAiB,GAAG,SAAS,EACpC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CA+C5C"}
@@ -0,0 +1,159 @@
1
+ import { mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ export function railwayPostgresStatusArgs(plan, options) {
5
+ const args = ["status"];
6
+ if (options.project)
7
+ args.push("--project", options.project);
8
+ args.push("--environment", plan.environment, "--json");
9
+ return args;
10
+ }
11
+ export function railwayPostgresReferenceArgs(plan, options, appService, databaseService) {
12
+ const reference = "${{" + databaseService + ".DATABASE_URL}}";
13
+ const args = ["variable", "set", `DATABASE_URL=${reference}`, "--service", appService];
14
+ if (options.project)
15
+ args.push("--project", options.project);
16
+ args.push("--environment", plan.environment, "--skip-deploys", "--json");
17
+ return args;
18
+ }
19
+ export function parseRailwayEnvironmentServices(text, environment) {
20
+ const parsed = parseJsonRecord(text, "Railway status");
21
+ const projectId = stringField(parsed, "id");
22
+ const environments = edgeNodes(parsed.environments);
23
+ const selected = environments.find((entry) => stringField(entry, "name") === environment);
24
+ const instances = edgeNodes(selected?.serviceInstances);
25
+ const services = instances.flatMap((instance) => {
26
+ const name = stringField(instance, "serviceName") ?? stringField(instance, "name");
27
+ if (!name)
28
+ return [];
29
+ const id = stringField(instance, "serviceId") ?? stringField(instance, "id");
30
+ return [{ name, ...(id ? { id } : {}) }];
31
+ });
32
+ return { ...(projectId ? { projectId } : {}), services };
33
+ }
34
+ export async function ensureRailwayPostgres(state, plan, options) {
35
+ const intent = railwayPostgresIntent(state);
36
+ if (!intent)
37
+ return undefined;
38
+ const railwayBin = options.railwayBin ?? "railway";
39
+ const commandOptions = deployCommandOptions(options);
40
+ const statusResult = await options.runCommand(railwayBin, railwayPostgresStatusArgs(plan, options), commandOptions);
41
+ if (statusResult.exitCode !== 0) {
42
+ throw new Error(`Railway Postgres preflight failed with exit code ${statusResult.exitCode}.`);
43
+ }
44
+ const status = parseRailwayEnvironmentServices(statusResult.stdout, plan.environment);
45
+ let database = status.services.find((service) => service.name.toLowerCase() === intent.databaseService.toLowerCase());
46
+ const appService = resolveAppService(options.service, status.services, database?.name);
47
+ let provisionStatus = "reused";
48
+ if (!database) {
49
+ if (!intent.provision) {
50
+ throw new Error(`Railway Postgres service "${intent.databaseService}" does not exist and provisioning is disabled.`);
51
+ }
52
+ if (intent.databaseService !== "Postgres") {
53
+ throw new Error(`Railway CLI provisioning creates the default "Postgres" service; ` +
54
+ `databaseService "${intent.databaseService}" must already exist with provision: false.`);
55
+ }
56
+ database = await provisionRailwayPostgres(status.projectId ?? options.project, intent.databaseService, plan, options);
57
+ provisionStatus = "created";
58
+ }
59
+ const referenceArgs = railwayPostgresReferenceArgs(plan, options, appService, database.name);
60
+ const referenceResult = await options.runCommand(railwayBin, referenceArgs, commandOptions);
61
+ if (referenceResult.exitCode !== 0) {
62
+ throw new Error(`Railway Postgres DATABASE_URL wiring failed with exit code ${referenceResult.exitCode}.`);
63
+ }
64
+ return {
65
+ status: provisionStatus,
66
+ service: database,
67
+ appService,
68
+ connectionEnv: "DATABASE_URL",
69
+ reference: "${{" + database.name + ".DATABASE_URL}}"
70
+ };
71
+ }
72
+ function railwayPostgresIntent(state) {
73
+ if (state?.kind !== "postgres" || state.options?.provider !== "railway")
74
+ return undefined;
75
+ const configuredService = state.options.databaseService;
76
+ return {
77
+ databaseService: typeof configuredService === "string" && configuredService.trim()
78
+ ? configuredService.trim()
79
+ : "Postgres",
80
+ provision: state.options.provision !== false
81
+ };
82
+ }
83
+ function resolveAppService(configuredService, services, databaseService) {
84
+ if (configuredService)
85
+ return configuredService;
86
+ const candidates = services.filter((service) => service.name !== databaseService);
87
+ if (candidates.length === 1)
88
+ return candidates[0].name;
89
+ throw new Error("Railway Postgres provisioning requires an application service. Set railwayDeploy({ service: \"...\" }) or pass --railway-service.");
90
+ }
91
+ async function provisionRailwayPostgres(project, expectedService, plan, options) {
92
+ if (!project)
93
+ throw new Error("Railway Postgres provisioning could not resolve the Railway project ID.");
94
+ const workspace = mkdtempSync(join(tmpdir(), "openeve-railway-postgres-"));
95
+ const railwayBin = options.railwayBin ?? "railway";
96
+ const commandOptions = { ...deployCommandOptions(options), cwd: workspace };
97
+ try {
98
+ const linkResult = await options.runCommand(railwayBin, [
99
+ "link",
100
+ "--project",
101
+ project,
102
+ "--environment",
103
+ plan.environment,
104
+ "--json"
105
+ ], commandOptions);
106
+ if (linkResult.exitCode !== 0) {
107
+ throw new Error(`Railway Postgres project linking failed with exit code ${linkResult.exitCode}.`);
108
+ }
109
+ const addResult = await options.runCommand(railwayBin, ["add", "--database", "postgres", "--json"], commandOptions);
110
+ if (addResult.exitCode !== 0) {
111
+ throw new Error(`Railway Postgres provisioning failed with exit code ${addResult.exitCode}.`);
112
+ }
113
+ return parseCreatedRailwayService(addResult.stdout, expectedService);
114
+ }
115
+ finally {
116
+ rmSync(workspace, { recursive: true, force: true });
117
+ }
118
+ }
119
+ function parseCreatedRailwayService(text, fallbackName) {
120
+ const parsed = parseJsonRecord(text, "railway add --database postgres");
121
+ const service = isRecord(parsed.service) ? parsed.service : parsed;
122
+ const name = stringField(service, "name") ?? stringField(service, "serviceName") ?? fallbackName;
123
+ const id = stringField(service, "id") ?? stringField(service, "serviceId");
124
+ return { name, ...(id ? { id } : {}) };
125
+ }
126
+ function edgeNodes(value) {
127
+ if (!isRecord(value) || !Array.isArray(value.edges))
128
+ return [];
129
+ return value.edges.flatMap((edge) => {
130
+ if (!isRecord(edge) || !isRecord(edge.node))
131
+ return [];
132
+ return [edge.node];
133
+ });
134
+ }
135
+ function parseJsonRecord(text, command) {
136
+ try {
137
+ const parsed = JSON.parse(text);
138
+ if (isRecord(parsed))
139
+ return parsed;
140
+ }
141
+ catch {
142
+ // Fall through to the actionable response-shape error.
143
+ }
144
+ throw new Error(`${command} did not return supported JSON. Update the Railway CLI and retry.`);
145
+ }
146
+ function stringField(value, key) {
147
+ const field = value?.[key];
148
+ return typeof field === "string" ? field : undefined;
149
+ }
150
+ function deployCommandOptions(options) {
151
+ return {
152
+ ...(options.cwd ? { cwd: options.cwd } : {}),
153
+ ...(options.env ? { env: options.env } : {})
154
+ };
155
+ }
156
+ function isRecord(value) {
157
+ return typeof value === "object" && value !== null && !Array.isArray(value);
158
+ }
159
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@assemblyline-agents/railway",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "default": "./dist/index.js"
9
+ }
10
+ },
11
+ "dependencies": {
12
+ "@assemblyline-agents/core": "0.1.0"
13
+ },
14
+ "description": "Official OpenEve Railway deployment plugin.",
15
+ "files": [
16
+ "dist",
17
+ "skills"
18
+ ],
19
+ "engines": {
20
+ "node": ">=22.19.0"
21
+ },
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/jasonbadeaux/openeve.git",
26
+ "directory": "packages/railway"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/jasonbadeaux/openeve/issues"
30
+ },
31
+ "homepage": "https://github.com/jasonbadeaux/openeve#readme",
32
+ "author": "OpenEve contributors",
33
+ "keywords": [
34
+ "openeve",
35
+ "ai",
36
+ "agents",
37
+ "railway",
38
+ "deployment",
39
+ "hosting",
40
+ "plugin"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "scripts": {
46
+ "build": "tsc -p tsconfig.json",
47
+ "check": "tsc -p tsconfig.json --noEmit"
48
+ }
49
+ }
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: railway
3
+ description: Use configured Railway MCP tools for projects, services, variables, and deployments.
4
+ ---
5
+ # Railway
6
+ Resolve the workspace, project, environment, and service before reading configuration or deployment state.
7
+
8
+ The deployment owner configures Railway authorization. The connection scaffold is read-only; deployments, variables, services, and project changes require writes to be enabled with the configured approval gate.